diff --git a/src/wp-includes/rest-api.php b/src/wp-includes/rest-api.php
index e1403d71bd..1025836de5 100644
--- a/src/wp-includes/rest-api.php
+++ b/src/wp-includes/rest-api.php
@@ -193,6 +193,12 @@ function create_initial_rest_routes() {
 			$revisions_controller = new WP_REST_Revisions_Controller( $post_type->name );
 			$revisions_controller->register_routes();
 		}
+
+		if ( 'attachment' !== $post_type->name ) {
+			$autosaves_controller = new WP_REST_Autosaves_Controller( $post_type->name );
+			$autosaves_controller->register_routes();
+		}
+
 	}
 
 	// Post types.
@@ -233,10 +239,6 @@ function create_initial_rest_routes() {
 	// Settings.
 	$controller = new WP_REST_Settings_Controller;
 	$controller->register_routes();
-
-	// Themes.
-	$controller = new WP_REST_Themes_Controller;
-	$controller->register_routes();
 }
 
 /**
diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-autosaves-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-autosaves-controller.php
new file mode 100644
index 0000000000..0f650821e3
--- /dev/null
+++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-autosaves-controller.php
@@ -0,0 +1,387 @@
+<?php
+/**
+ * REST API: WP_REST_Autosaves_Controller class.
+ *
+ * @package WordPress
+ * @subpackage REST_API
+ * @since 5.0.0
+ */
+
+/**
+ * Core class used to access autosaves via the REST API.
+ *
+ * @since 5.0.0
+ *
+ * @see WP_REST_Controller
+ */
+class WP_REST_Autosaves_Controller extends WP_REST_Revisions_Controller {
+
+	/**
+	 * Parent post type.
+	 *
+	 * @since 5.0.0
+	 * @var string
+	 */
+	private $parent_post_type;
+
+	/**
+	 * Parent post controller.
+	 *
+	 * @since 5.0.0
+	 * @var WP_REST_Controller
+	 */
+	private $parent_controller;
+
+	/**
+	 * Revision controller.
+	 *
+	 * @since 5.0.0
+	 * @var WP_REST_Controller
+	 */
+	private $revisions_controller;
+
+	/**
+	 * The base of the parent controller's route.
+	 *
+	 * @since 5.0.0
+	 * @var string
+	 */
+	private $parent_base;
+
+	/**
+	 * Constructor.
+	 *
+	 * @since 5.0.0
+	 *
+	 * @param string $parent_post_type Post type of the parent.
+	 */
+	public function __construct( $parent_post_type ) {
+		$this->parent_post_type = $parent_post_type;
+		$post_type_object       = get_post_type_object( $parent_post_type );
+
+		// Ensure that post type-specific controller logic is available.
+		$parent_controller_class = ! empty( $post_type_object->rest_controller_class ) ? $post_type_object->rest_controller_class : 'WP_REST_Posts_Controller';
+
+		$this->parent_controller    = new $parent_controller_class( $post_type_object->name );
+		$this->revisions_controller = new WP_REST_Revisions_Controller( $parent_post_type );
+		$this->rest_namespace       = 'wp/v2';
+		$this->rest_base            = 'autosaves';
+		$this->parent_base          = ! empty( $post_type_object->rest_base ) ? $post_type_object->rest_base : $post_type_object->name;
+	}
+
+	/**
+	 * Registers routes for autosaves.
+	 *
+	 * @since 5.0.0
+	 *
+	 * @see register_rest_route()
+	 */
+	public function register_routes() {
+		register_rest_route(
+			$this->rest_namespace,
+			'/' . $this->parent_base . '/(?P<parent>[\d]+)/' . $this->rest_base,
+			array(
+				'args'   => array(
+					'parent' => array(
+						'description' => __( 'The ID for the parent of the object.', 'gutenberg' ),
+						'type'        => 'integer',
+					),
+				),
+				array(
+					'methods'             => WP_REST_Server::READABLE,
+					'callback'            => array( $this, 'get_items' ),
+					'permission_callback' => array( $this->revisions_controller, 'get_items_permissions_check' ),
+					'args'                => $this->get_collection_params(),
+				),
+				array(
+					'methods'             => WP_REST_Server::CREATABLE,
+					'callback'            => array( $this, 'create_item' ),
+					'permission_callback' => array( $this, 'create_item_permissions_check' ),
+					'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ),
+				),
+				'schema' => array( $this, 'get_public_item_schema' ),
+			)
+		);
+
+		register_rest_route(
+			$this->rest_namespace,
+			'/' . $this->parent_base . '/(?P<parent>[\d]+)/' . $this->rest_base . '/(?P<id>[\d]+)',
+			array(
+				'args'   => array(
+					'parent' => array(
+						'description' => __( 'The ID for the parent of the object.', 'gutenberg' ),
+						'type'        => 'integer',
+					),
+					'id'     => array(
+						'description' => __( 'The ID for the object.', 'gutenberg' ),
+						'type'        => 'integer',
+					),
+				),
+				array(
+					'methods'             => WP_REST_Server::READABLE,
+					'callback'            => array( $this, 'get_item' ),
+					'permission_callback' => array( $this->revisions_controller, 'get_item_permissions_check' ),
+					'args'                => array(
+						'context' => $this->get_context_param( array( 'default' => 'view' ) ),
+					),
+				),
+				'schema' => array( $this, 'get_public_item_schema' ),
+			)
+		);
+
+	}
+
+	/**
+	 * Get the parent post.
+	 *
+	 * @since 5.0.0
+	 *
+	 * @param int $parent_id Supplied ID.
+	 * @return WP_Post|WP_Error Post object if ID is valid, WP_Error otherwise.
+	 */
+	protected function get_parent( $parent_id ) {
+		return $this->revisions_controller->get_parent( $parent_id );
+	}
+
+	/**
+	 * Checks if a given request has access to create an autosave revision.
+	 *
+	 * Autosave revisions inherit permissions from the parent post,
+	 * check if the current user has permission to edit the post.
+	 *
+	 * @since 5.0.0
+	 *
+	 * @param WP_REST_Request $request Full details about the request.
+	 * @return true|WP_Error True if the request has access to create the item, WP_Error object otherwise.
+	 */
+	public function create_item_permissions_check( $request ) {
+		$id = $request->get_param( 'id' );
+		if ( empty( $id ) ) {
+			return new WP_Error( 'rest_post_invalid_id', __( 'Invalid item ID.', 'gutenberg' ), array( 'status' => 404 ) );
+		}
+
+		return $this->parent_controller->update_item_permissions_check( $request );
+	}
+
+	/**
+	 * Creates, updates or deletes an autosave revision.
+	 *
+	 * @since 5.0.0
+	 *
+	 * @param WP_REST_Request $request Full details about the request.
+	 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
+	 */
+	public function create_item( $request ) {
+
+		$post = get_post( $request->get_param( 'id' ) );
+
+		if ( is_wp_error( $post ) ) {
+			return $post;
+		}
+
+		$prepared_post     = $this->parent_controller->prepare_item_for_database( $request );
+		$prepared_post->ID = $post->ID;
+		$user_id           = get_current_user_id();
+
+		if ( ( 'draft' === $post->post_status || 'auto-draft' === $post->post_status ) && $post->post_author == $user_id ) {
+			// Draft posts for the same author: autosaving updates the post and does not create a revision.
+			// Convert the post object to an array and add slashes, wp_update_post expects escaped array.
+			$autosave_id = wp_update_post( wp_slash( (array) $prepared_post ), true );
+		} else {
+			// Non-draft posts: create or update the post autosave.
+			$autosave_id = $this->create_post_autosave( (array) $prepared_post );
+		}
+
+		if ( is_wp_error( $autosave_id ) ) {
+			return $autosave_id;
+		}
+
+		$autosave = get_post( $autosave_id );
+		$request->set_param( 'context', 'edit' );
+
+		$response = $this->prepare_item_for_response( $autosave, $request );
+		$response = rest_ensure_response( $response );
+
+		return $response;
+	}
+
+	/**
+	 * Get the autosave, if the ID is valid.
+	 *
+	 * @since 5.0.0
+	 *
+	 * @param WP_REST_Request $request Full data about the request.
+	 * @return WP_Post|WP_Error Revision post object if ID is valid, WP_Error otherwise.
+	 */
+	public function get_item( $request ) {
+		$parent_id = (int) $request->get_param( 'parent' );
+
+		if ( $parent_id <= 0 ) {
+			return new WP_Error( 'rest_post_invalid_id', __( 'Invalid parent post ID.', 'gutenberg' ), array( 'status' => 404 ) );
+		}
+
+		$autosave = wp_get_post_autosave( $parent_id );
+
+		if ( ! $autosave ) {
+			return new WP_Error( 'rest_post_no_autosave', __( 'There is no autosave revision for this post.', 'gutenberg' ), array( 'status' => 404 ) );
+		}
+
+		$response = $this->prepare_item_for_response( $autosave, $request );
+		return $response;
+	}
+
+	/**
+	 * Gets a collection of autosaves using wp_get_post_autosave.
+	 *
+	 * Contains the user's autosave, for empty if it doesn't exist.
+	 *
+	 * @since 5.0.0
+	 *
+	 * @param WP_REST_Request $request Full data about the request.
+	 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
+	 */
+	public function get_items( $request ) {
+		$parent = $this->get_parent( $request->get_param( 'parent' ) );
+		if ( is_wp_error( $parent ) ) {
+			return $parent;
+		}
+
+		$response  = array();
+		$parent_id = $parent->ID;
+		$revisions = wp_get_post_revisions( $parent_id, array( 'check_enabled' => false ) );
+
+		foreach ( $revisions as $revision ) {
+			if ( false !== strpos( $revision->post_name, "{$parent_id}-autosave" ) ) {
+				$data       = $this->prepare_item_for_response( $revision, $request );
+				$response[] = $this->prepare_response_for_collection( $data );
+			}
+		}
+
+		return rest_ensure_response( $response );
+	}
+
+
+	/**
+	 * Retrieves the autosave's schema, conforming to JSON Schema.
+	 *
+	 * @since 5.0.0
+	 *
+	 * @return array Item schema data.
+	 */
+	public function get_item_schema() {
+		$schema = $this->revisions_controller->get_item_schema();
+
+		$schema['properties']['preview_link'] = array(
+			'description' => __( 'Preview link for the post.', 'gutenberg' ),
+			'type'        => 'string',
+			'format'      => 'uri',
+			'context'     => array( 'edit' ),
+			'readonly'    => true,
+		);
+
+		return $schema;
+	}
+
+	/**
+	 * Creates autosave for the specified post.
+	 *
+	 * From wp-admin/post.php.
+	 *
+	 * @since 5.0.0
+	 *
+	 * @param mixed $post_data Associative array containing the post data.
+	 * @return mixed The autosave revision ID or WP_Error.
+	 */
+	public function create_post_autosave( $post_data ) {
+
+		$post_id = (int) $post_data['ID'];
+		$post    = get_post( $post_id );
+
+		if ( is_wp_error( $post ) ) {
+			return $post;
+		}
+
+		$user_id = get_current_user_id();
+
+		// Store one autosave per author. If there is already an autosave, overwrite it.
+		$old_autosave = wp_get_post_autosave( $post_id, $user_id );
+
+		if ( $old_autosave ) {
+			$new_autosave                = _wp_post_revision_data( $post_data, true );
+			$new_autosave['ID']          = $old_autosave->ID;
+			$new_autosave['post_author'] = $user_id;
+
+			// If the new autosave has the same content as the post, delete the autosave.
+			$autosave_is_different = false;
+
+			foreach ( array_intersect( array_keys( $new_autosave ), array_keys( _wp_post_revision_fields( $post ) ) ) as $field ) {
+				if ( normalize_whitespace( $new_autosave[ $field ] ) != normalize_whitespace( $post->$field ) ) {
+					$autosave_is_different = true;
+					break;
+				}
+			}
+
+			if ( ! $autosave_is_different ) {
+				wp_delete_post_revision( $old_autosave->ID );
+				return new WP_Error( 'rest_autosave_no_changes', __( 'There is nothing to save. The autosave and the post content are the same.', 'gutenberg' ), array( 'status' => 400 ) );
+			}
+
+			/**
+			 * This filter is documented in wp-admin/post.php.
+			 */
+			do_action( 'wp_creating_autosave', $new_autosave );
+
+			// wp_update_post expects escaped array.
+			return wp_update_post( wp_slash( $new_autosave ) );
+		}
+
+		// Create the new autosave as a special post revision.
+		return _wp_put_post_revision( $post_data, true );
+	}
+
+	/**
+	 * Prepares the revision for the REST response.
+	 *
+	 * @since 5.0.0
+	 *
+	 * @param WP_Post         $post    Post revision object.
+	 * @param WP_REST_Request $request Request object.
+	 *
+	 * @return WP_REST_Response Response object.
+	 */
+	public function prepare_item_for_response( $post, $request ) {
+
+		$response = $this->revisions_controller->prepare_item_for_response( $post, $request );
+
+		$schema = $this->get_item_schema();
+
+		if ( ! empty( $schema['properties']['preview_link'] ) ) {
+			$parent_id          = wp_is_post_autosave( $post );
+			$preview_post_id    = false === $parent_id ? $post->ID : $parent_id;
+			$preview_query_args = array();
+
+			if ( false !== $parent_id ) {
+				$preview_query_args['preview_id']    = $parent_id;
+				$preview_query_args['preview_nonce'] = wp_create_nonce( 'post_preview_' . $parent_id );
+			}
+
+			$response->data['preview_link'] = get_preview_post_link( $preview_post_id, $preview_query_args );
+		}
+
+		$context        = ! empty( $request['context'] ) ? $request['context'] : 'view';
+		$response->data = $this->filter_response_by_context( $response->data, $context );
+
+		/**
+		 * Filters a revision returned from the API.
+		 *
+		 * Allows modification of the revision right before it is returned.
+		 *
+		 * @since 5.0.0
+		 *
+		 * @param WP_REST_Response $response The response object.
+		 * @param WP_Post          $post     The original revision object.
+		 * @param WP_REST_Request  $request  Request used to generate the response.
+		 */
+		return apply_filters( 'rest_prepare_autosave', $response, $post, $request );
+	}
+}
diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-controller.php
index 04bd1580f7..3bc6b59091 100644
--- a/src/wp-includes/rest-api/endpoints/class-wp-rest-controller.php
+++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-controller.php
@@ -385,18 +385,12 @@ abstract class WP_REST_Controller {
 
 		$additional_fields = $this->get_additional_fields();
 
-		$requested_fields = $this->get_fields_for_response( $request );
-
 		foreach ( $additional_fields as $field_name => $field_options ) {
 
 			if ( ! $field_options['get_callback'] ) {
 				continue;
 			}
 
-			if ( ! in_array( $field_name, $requested_fields, true ) ) {
-				continue;
-			}
-
 			$object[ $field_name ] = call_user_func( $field_options['get_callback'], $object, $field_name, $request, $this->get_object_type() );
 		}
 
diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-themes-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-themes-controller.php
deleted file mode 100644
index 4aa7db4f6f..0000000000
--- a/src/wp-includes/rest-api/endpoints/class-wp-rest-themes-controller.php
+++ /dev/null
@@ -1,231 +0,0 @@
-<?php
-/**
- * REST API: WP_REST_Themes_Controller class
- *
- * @package WordPress
- * @subpackage REST_API
- * @since 5.0.0
- */
-
-/**
- * Core class used to manage themes via the REST API.
- *
- * @since 5.0.0
- *
- * @see WP_REST_Controller
- */
-class WP_REST_Themes_Controller extends WP_REST_Controller {
-
-	/**
-	 * Constructor.
-	 *
-	 * @since 5.0.0
-	 */
-	public function __construct() {
-		$this->namespace = 'wp/v2';
-		$this->rest_base = 'themes';
-	}
-
-	/**
-	 * Registers the routes for the objects of the controller.
-	 *
-	 * @since 5.0.0
-	 *
-	 * @see register_rest_route()
-	 */
-	public function register_routes() {
-		register_rest_route(
-			$this->namespace,
-			'/' . $this->rest_base,
-			array(
-				array(
-					'methods'             => WP_REST_Server::READABLE,
-					'callback'            => array( $this, 'get_items' ),
-					'permission_callback' => array( $this, 'get_items_permissions_check' ),
-					'args'                => $this->get_collection_params(),
-				),
-				'schema' => array( $this, 'get_item_schema' ),
-			)
-		);
-	}
-
-	/**
-	 * Checks if a given request has access to read the theme.
-	 *
-	 * @since 5.0.0
-	 *
-	 * @param WP_REST_Request $request Full details about the request.
-	 * @return true|WP_Error True if the request has read access for the item, otherwise WP_Error object.
-	 */
-	public function get_items_permissions_check( $request ) {
-		if ( ! is_user_logged_in() || ! current_user_can( 'edit_posts' ) ) {
-			return new WP_Error( 'rest_user_cannot_view', __( 'Sorry, you are not allowed to view themes.' ), array( 'status' => rest_authorization_required_code() ) );
-		}
-
-		return true;
-	}
-
-	/**
-	 * Retrieves a collection of themes.
-	 *
-	 * @since 5.0.0
-	 *
-	 * @param WP_REST_Request $request Full details about the request.
-	 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
-	 */
-	public function get_items( $request ) {
-		// Retrieve the list of registered collection query parameters.
-		$registered = $this->get_collection_params();
-		$themes     = array();
-
-		if ( isset( $registered['status'], $request['status'] ) && in_array( 'active', $request['status'], true ) ) {
-			$active_theme = wp_get_theme();
-			$active_theme = $this->prepare_item_for_response( $active_theme, $request );
-			$themes[]     = $this->prepare_response_for_collection( $active_theme );
-		}
-
-		$response = rest_ensure_response( $themes );
-
-		$response->header( 'X-WP-Total', count( $themes ) );
-		$response->header( 'X-WP-TotalPages', count( $themes ) );
-
-		return $response;
-	}
-
-	/**
-	 * Prepares a single theme output for response.
-	 *
-	 * @since 5.0.0
-	 *
-	 * @param WP_Theme        $theme   Theme object.
-	 * @param WP_REST_Request $request Request object.
-	 * @return WP_REST_Response Response object.
-	 */
-	public function prepare_item_for_response( $theme, $request ) {
-		$data   = array();
-		$fields = $this->get_fields_for_response( $request );
-
-		if ( in_array( 'theme_supports', $fields, true ) ) {
-			$formats                           = get_theme_support( 'post-formats' );
-			$formats                           = is_array( $formats ) ? array_values( $formats[0] ) : array();
-			$formats                           = array_merge( array( 'standard' ), $formats );
-			$data['theme_supports']['formats'] = $formats;
-
-			$data['theme_supports']['post-thumbnails'] = false;
-			$post_thumbnails                           = get_theme_support( 'post-thumbnails' );
-
-			if ( $post_thumbnails ) {
-				// $post_thumbnails can contain a nested array of post types.
-				// e.g. array( array( 'post', 'page' ) ).
-				$data['theme_supports']['post-thumbnails'] = is_array( $post_thumbnails ) ? $post_thumbnails[0] : true;
-			}
-		}
-
-		$data = $this->add_additional_fields_to_object( $data, $request );
-
-		// Wrap the data in a response object.
-		$response = rest_ensure_response( $data );
-
-		/**
-		 * Filters theme data returned from the REST API.
-		 *
-		 * @since 5.0.0
-		 *
-		 * @param WP_REST_Response $response The response object.
-		 * @param WP_Theme         $theme    Theme object used to create response.
-		 * @param WP_REST_Request  $request  Request object.
-		 */
-		return apply_filters( 'rest_prepare_theme', $response, $theme, $request );
-	}
-
-	/**
-	 * Retrieves the theme's schema, conforming to JSON Schema.
-	 *
-	 * @since 5.0.0
-	 *
-	 * @return array Item schema data.
-	 */
-	public function get_item_schema() {
-		$schema = array(
-			'$schema'    => 'http://json-schema.org/draft-04/schema#',
-			'title'      => 'theme',
-			'type'       => 'object',
-			'properties' => array(
-				'theme_supports' => array(
-					'description' => __( 'Features supported by this theme.' ),
-					'type'        => 'array',
-					'readonly'    => true,
-					'properties'  => array(
-						'formats'         => array(
-							'description' => __( 'Post formats supported.' ),
-							'type'        => 'array',
-							'readonly'    => true,
-						),
-						'post-thumbnails' => array(
-							'description' => __( 'Whether the theme supports post thumbnails.' ),
-							'type'        => array( 'array', 'bool' ),
-							'readonly'    => true,
-						),
-					),
-				),
-			),
-		);
-
-		return $this->add_additional_fields_schema( $schema );
-	}
-
-	/**
-	 * Retrieves the search params for the themes collection.
-	 *
-	 * @since 5.0.0
-	 *
-	 * @return array Collection parameters.
-	 */
-	public function get_collection_params() {
-		$query_params = parent::get_collection_params();
-
-		$query_params['status'] = array(
-			'description'       => __( 'Limit result set to themes assigned one or more statuses.' ),
-			'type'              => 'array',
-			'items'             => array(
-				'enum' => array( 'active' ),
-				'type' => 'string',
-			),
-			'required'          => true,
-			'sanitize_callback' => array( $this, 'sanitize_theme_status' ),
-		);
-
-		/**
-		 * Filter collection parameters for the themes controller.
-		 *
-		 * @since 5.0.0
-		 *
-		 * @param array        $query_params JSON Schema-formatted collection parameters.
-		 */
-		return apply_filters( 'rest_themes_collection_params', $query_params );
-	}
-
-	/**
-	 * Sanitizes and validates the list of theme status.
-	 *
-	 * @since 5.0.0
-	 *
-	 * @param  string|array    $statuses  One or more theme statuses.
-	 * @param  WP_REST_Request $request   Full details about the request.
-	 * @param  string          $parameter Additional parameter to pass to validation.
-	 * @return array|WP_Error A list of valid statuses, otherwise WP_Error object.
-	 */
-	public function sanitize_theme_status( $statuses, $request, $parameter ) {
-		$statuses = wp_parse_slug_list( $statuses );
-
-		foreach ( $statuses as $status ) {
-			$result = rest_validate_request_arg( $status, $request, $parameter );
-
-			if ( is_wp_error( $result ) ) {
-				return $result;
-			}
-		}
-
-		return $statuses;
-	}
-}
diff --git a/src/wp-settings.php b/src/wp-settings.php
index 44c8a91a07..f4f2ba0d88 100644
--- a/src/wp-settings.php
+++ b/src/wp-settings.php
@@ -229,12 +229,12 @@ require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-attachments-contro
 require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-post-types-controller.php' );
 require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-post-statuses-controller.php' );
 require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-revisions-controller.php' );
+require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-autosaves-controller.php' );
 require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-taxonomies-controller.php' );
 require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-terms-controller.php' );
 require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-users-controller.php' );
 require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-comments-controller.php' );
 require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-settings-controller.php' );
-require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-themes-controller.php' );
 require( ABSPATH . WPINC . '/rest-api/fields/class-wp-rest-meta-fields.php' );
 require( ABSPATH . WPINC . '/rest-api/fields/class-wp-rest-comment-meta-fields.php' );
 require( ABSPATH . WPINC . '/rest-api/fields/class-wp-rest-post-meta-fields.php' );
diff --git a/tests/phpunit/tests/rest-api/rest-autosaves-controller.php b/tests/phpunit/tests/rest-api/rest-autosaves-controller.php
new file mode 100644
index 0000000000..6805b61552
--- /dev/null
+++ b/tests/phpunit/tests/rest-api/rest-autosaves-controller.php
@@ -0,0 +1,513 @@
+<?php
+/**
+ * Unit tests covering WP_REST_Autosaves_Controller functionality.
+ *
+ * @package WordPress
+ * @subpackage REST API
+ */
+
+/**
+ * @group restapi-autosave
+ * @group restapi
+ */
+class WP_Test_REST_Autosaves_Controller extends WP_Test_REST_Post_Type_Controller_Testcase {
+	protected static $post_id;
+	protected static $page_id;
+
+	protected static $autosave_post_id;
+	protected static $autosave_page_id;
+
+	protected static $editor_id;
+	protected static $contributor_id;
+
+	protected function set_post_data( $args = array() ) {
+		$defaults = array(
+			'title'   => 'Post Title',
+			'content' => 'Post content',
+			'excerpt' => 'Post excerpt',
+			'name'    => 'test',
+			'author'  => get_current_user_id(),
+		);
+
+		return wp_parse_args( $args, $defaults );
+	}
+
+	protected function check_create_autosave_response( $response ) {
+		$this->assertNotInstanceOf( 'WP_Error', $response );
+		$response = rest_ensure_response( $response );
+		$data = $response->get_data();
+
+		$this->assertArrayHasKey( 'content', $data );
+		$this->assertArrayHasKey( 'excerpt', $data );
+		$this->assertArrayHasKey( 'title', $data );
+	}
+
+	public static function wpSetUpBeforeClass( $factory ) {
+		self::$post_id = $factory->post->create();
+		self::$page_id = $factory->post->create( array( 'post_type' => 'page' ) );
+
+		self::$editor_id      = $factory->user->create(
+			array(
+				'role' => 'editor',
+			)
+		);
+		self::$contributor_id = $factory->user->create(
+			array(
+				'role' => 'contributor',
+			)
+		);
+
+		wp_set_current_user( self::$editor_id );
+
+		// Create an autosave.
+		self::$autosave_post_id = wp_create_post_autosave(
+			array(
+				'post_content' => 'This content is better.',
+				'post_ID'      => self::$post_id,
+				'post_type'    => 'post',
+			)
+		);
+
+		self::$autosave_page_id = wp_create_post_autosave(
+			array(
+				'post_content' => 'This content is better.',
+				'post_ID'      => self::$page_id,
+				'post_type'    => 'post',
+			)
+		);
+
+	}
+
+	public static function wpTearDownAfterClass() {
+		// Also deletes revisions.
+		wp_delete_post( self::$post_id, true );
+		wp_delete_post( self::$page_id, true );
+
+		self::delete_user( self::$editor_id );
+		self::delete_user( self::$contributor_id );
+	}
+
+	public function setUp() {
+		parent::setUp();
+		wp_set_current_user( self::$editor_id );
+
+		$this->post_autosave = wp_get_post_autosave( self::$post_id );
+	}
+
+	public function test_register_routes() {
+		$routes = rest_get_server()->get_routes();
+		$this->assertArrayHasKey( '/wp/v2/posts/(?P<parent>[\d]+)/autosaves', $routes );
+		$this->assertArrayHasKey( '/wp/v2/posts/(?P<parent>[\d]+)/autosaves/(?P<id>[\d]+)', $routes );
+		$this->assertArrayHasKey( '/wp/v2/pages/(?P<parent>[\d]+)/autosaves', $routes );
+		$this->assertArrayHasKey( '/wp/v2/pages/(?P<parent>[\d]+)/autosaves/(?P<id>[\d]+)', $routes );
+	}
+
+	public function test_context_param() {
+		// Collection
+		$request  = new WP_REST_Request( 'OPTIONS', '/wp/v2/posts/' . self::$post_id . '/autosaves' );
+		$response = rest_get_server()->dispatch( $request );
+		$data     = $response->get_data();
+		$this->assertEquals( 'view', $data['endpoints'][0]['args']['context']['default'] );
+		$this->assertEqualSets( array( 'view', 'edit', 'embed' ), $data['endpoints'][0]['args']['context']['enum'] );
+		// Single
+		$request  = new WP_REST_Request( 'OPTIONS', '/wp/v2/posts/' . self::$post_id . '/autosaves/' . self::$autosave_post_id );
+		$response = rest_get_server()->dispatch( $request );
+		$data     = $response->get_data();
+		$this->assertEquals( 'view', $data['endpoints'][0]['args']['context']['default'] );
+		$this->assertEqualSets( array( 'view', 'edit', 'embed' ), $data['endpoints'][0]['args']['context']['enum'] );	}
+
+	public function test_get_items() {
+		wp_set_current_user( self::$editor_id );
+		$request  = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/autosaves' );
+		$response = rest_get_server()->dispatch( $request );
+		$data     = $response->get_data();
+		$this->assertEquals( 200, $response->get_status() );
+		$this->assertCount( 1, $data );
+
+		$this->assertEquals( self::$autosave_post_id, $data[0]['id'] );
+
+		$this->check_get_autosave_response( $data[0], $this->post_autosave );
+	}
+
+	public function test_get_items_no_permission() {
+		wp_set_current_user( 0 );
+		$request  = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/autosaves' );
+		$response = rest_get_server()->dispatch( $request );
+		$this->assertErrorResponse( 'rest_cannot_read', $response, 401 );
+		wp_set_current_user( self::$contributor_id );
+		$response = rest_get_server()->dispatch( $request );
+		$this->assertErrorResponse( 'rest_cannot_read', $response, 403 );
+	}
+
+	public function test_get_items_missing_parent() {
+		wp_set_current_user( self::$editor_id );
+		$request  = new WP_REST_Request( 'GET', '/wp/v2/posts/' . REST_TESTS_IMPOSSIBLY_HIGH_NUMBER . '/autosaves' );
+		$response = rest_get_server()->dispatch( $request );
+		$this->assertErrorResponse( 'rest_post_invalid_parent', $response, 404 );
+	}
+
+	public function test_get_items_invalid_parent_post_type() {
+		wp_set_current_user( self::$editor_id );
+		$request  = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$page_id . '/autosaves' );
+		$response = rest_get_server()->dispatch( $request );
+		$this->assertErrorResponse( 'rest_post_invalid_parent', $response, 404 );
+	}
+
+	public function test_get_item() {
+		wp_set_current_user( self::$editor_id );
+		$request  = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/autosaves/' . self::$autosave_post_id );
+		$response = rest_get_server()->dispatch( $request );
+		$this->assertEquals( 200, $response->get_status() );
+		$data     = $response->get_data();
+
+		$this->check_get_autosave_response( $response, $this->post_autosave );
+		$fields = array(
+			'author',
+			'date',
+			'date_gmt',
+			'modified',
+			'modified_gmt',
+			'guid',
+			'id',
+			'parent',
+			'slug',
+			'title',
+			'excerpt',
+			'content',
+		);
+		$this->assertEqualSets( $fields, array_keys( $data ) );
+		$this->assertSame( self::$editor_id, $data['author'] );
+	}
+
+	public function test_get_item_embed_context() {
+		wp_set_current_user( self::$editor_id );
+		$request  = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/autosaves/' . self::$autosave_post_id );
+		$request->set_param( 'context', 'embed' );
+		$response = rest_get_server()->dispatch( $request );
+		$fields   = array(
+			'author',
+			'date',
+			'id',
+			'parent',
+			'slug',
+			'title',
+			'excerpt',
+		);
+		$data     = $response->get_data();
+		$this->assertEqualSets( $fields, array_keys( $data ) );
+	}
+
+	public function test_get_item_no_permission() {
+		$request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/autosaves/' . self::$autosave_post_id );
+		wp_set_current_user( self::$contributor_id );
+		$response = rest_get_server()->dispatch( $request );
+		$this->assertErrorResponse( 'rest_cannot_read', $response, 403 );
+	}
+
+	public function test_get_item_missing_parent() {
+		wp_set_current_user( self::$editor_id );
+		$request  = new WP_REST_Request( 'GET', '/wp/v2/posts/' . REST_TESTS_IMPOSSIBLY_HIGH_NUMBER . '/autosaves/' . self::$autosave_post_id );
+		$response = rest_get_server()->dispatch( $request );
+		$this->assertErrorResponse( 'rest_post_invalid_parent', $response, 404 );
+
+	}
+
+	public function test_get_item_invalid_parent_post_type() {
+		wp_set_current_user( self::$editor_id );
+		$request  = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$page_id . '/autosaves' );
+		$response = rest_get_server()->dispatch( $request );
+		$this->assertErrorResponse( 'rest_post_invalid_parent', $response, 404 );
+	}
+
+	public function test_delete_item() {
+		// Doesn't exist.
+	}
+
+	public function test_prepare_item() {
+		wp_set_current_user( self::$editor_id );
+		$request  = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/autosaves/' . self::$autosave_post_id );
+		$response = rest_get_server()->dispatch( $request );
+		$this->assertEquals( 200, $response->get_status() );
+		$this->check_get_autosave_response( $response, $this->post_autosave );
+	}
+
+	public function test_get_item_schema() {
+		$request    = new WP_REST_Request( 'OPTIONS', '/wp/v2/posts/' . self::$post_id . '/autosaves' );
+		$response   = rest_get_server()->dispatch( $request );
+		$data       = $response->get_data();
+		$properties = $data['schema']['properties'];
+		$this->assertEquals( 13, count( $properties ) );
+		$this->assertArrayHasKey( 'author', $properties );
+		$this->assertArrayHasKey( 'content', $properties );
+		$this->assertArrayHasKey( 'date', $properties );
+		$this->assertArrayHasKey( 'date_gmt', $properties );
+		$this->assertArrayHasKey( 'excerpt', $properties );
+		$this->assertArrayHasKey( 'guid', $properties );
+		$this->assertArrayHasKey( 'id', $properties );
+		$this->assertArrayHasKey( 'modified', $properties );
+		$this->assertArrayHasKey( 'modified_gmt', $properties );
+		$this->assertArrayHasKey( 'parent', $properties );
+		$this->assertArrayHasKey( 'slug', $properties );
+		$this->assertArrayHasKey( 'title', $properties );
+	}
+
+	public function test_create_item() {
+		wp_set_current_user( self::$editor_id );
+
+		$request  = new WP_REST_Request( 'POST', '/wp/v2/posts/' . self::$post_id . '/autosaves' );
+		$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );
+
+		$params = $this->set_post_data(
+			array(
+				'id' => self::$post_id,
+			)
+		);
+		$request->set_body_params( $params );
+		$response = rest_get_server()->dispatch( $request );
+
+		$this->check_create_autosave_response( $response );
+	}
+
+	public function test_update_item() {
+		wp_set_current_user( self::$editor_id );
+		$request  = new WP_REST_Request( 'POST', '/wp/v2/posts/' . self::$post_id . '/autosaves' );
+		$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );
+
+		$params = $this->set_post_data(
+			array(
+				'id'     => self::$post_id,
+				'author' => self::$contributor_id,
+			)
+		);
+
+		$request->set_body_params( $params );
+		$response = rest_get_server()->dispatch( $request );
+
+		$this->check_create_autosave_response( $response );
+	}
+
+	public function test_update_item_nopriv() {
+		wp_set_current_user( self::$contributor_id );
+
+		$request = new WP_REST_Request( 'POST', '/wp/v2/posts/' . self::$post_id . '/autosaves' );
+		$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );
+
+		$params = $this->set_post_data(
+			array(
+				'id'     => self::$post_id,
+				'author' => self::$editor_id,
+			)
+		);
+
+		$request->set_body_params( $params );
+		$response = rest_get_server()->dispatch( $request );
+
+		$this->assertErrorResponse( 'rest_cannot_edit', $response, 403 );
+	}
+
+	public function test_rest_autosave_published_post() {
+		wp_set_current_user( self::$editor_id );
+
+		$request  = new WP_REST_Request( 'POST', '/wp/v2/posts/' . self::$post_id . '/autosaves' );
+		$request->add_header( 'content-type', 'application/json' );
+
+		$current_post = get_post( self::$post_id );
+
+		$autosave_data = $this->set_post_data(
+			array(
+				'id'      => self::$post_id,
+				'content' => 'Updated post \ content',
+				'excerpt' => $current_post->post_excerpt,
+				'title'   => $current_post->post_title,
+			)
+		);
+
+		$request->set_body( wp_json_encode( $autosave_data ) );
+		$response = rest_get_server()->dispatch( $request );
+		$new_data = $response->get_data();
+
+		$this->assertEquals( $current_post->ID, $new_data['parent'] );
+		$this->assertEquals( $current_post->post_title, $new_data['title']['raw'] );
+		$this->assertEquals( $current_post->post_excerpt, $new_data['excerpt']['raw'] );
+		// Updated post_content
+		$this->assertNotEquals( $current_post->post_content, $new_data['content']['raw'] );
+
+		$autosave_post = wp_get_post_autosave( self::$post_id );
+		$this->assertEquals( $autosave_data['title'], $autosave_post->post_title );
+		$this->assertEquals( $autosave_data['content'], $autosave_post->post_content );
+		$this->assertEquals( $autosave_data['excerpt'], $autosave_post->post_excerpt );
+	}
+
+	public function test_rest_autosave_draft_post_same_author() {
+		wp_set_current_user( self::$editor_id );
+
+		$post_data = array(
+			'post_content' => 'Test post content',
+			'post_title'   => 'Test post title',
+			'post_excerpt' => 'Test post excerpt',
+		);
+		$post_id = wp_insert_post( $post_data );
+
+		$autosave_data = array(
+			'id' => $post_id,
+			'content' => 'Updated post \ content',
+			'title'   => 'Updated post title',
+		);
+
+		$request  = new WP_REST_Request( 'POST', '/wp/v2/posts/' . self::$post_id . '/autosaves' );
+		$request->add_header( 'content-type', 'application/json' );
+		$request->set_body( wp_json_encode( $autosave_data ) );
+
+		$response = rest_get_server()->dispatch( $request );
+		$new_data = $response->get_data();
+		$post = get_post( $post_id );
+
+		$this->assertEquals( $post_id, $new_data['id'] );
+		// The draft post should be updated.
+		$this->assertEquals( $autosave_data['content'], $new_data['content']['raw'] );
+		$this->assertEquals( $autosave_data['title'], $new_data['title']['raw'] );
+		$this->assertEquals( $autosave_data['content'], $post->post_content );
+		$this->assertEquals( $autosave_data['title'], $post->post_title );
+
+		// Not updated.
+		$this->assertEquals( $post_data['post_excerpt'], $post->post_excerpt );
+
+		wp_delete_post( $post_id );
+	}
+
+	public function test_rest_autosave_draft_post_different_author() {
+		wp_set_current_user( self::$editor_id );
+
+		$post_data = array(
+			'post_content' => 'Test post content',
+			'post_title'   => 'Test post title',
+			'post_excerpt' => 'Test post excerpt',
+			'post_author'  => self::$editor_id + 1,
+		);
+		$post_id = wp_insert_post( $post_data );
+
+		$autosave_data = array(
+			'id' => $post_id,
+			'content' => 'Updated post content',
+			'excerpt' => $post_data['post_excerpt'],
+			'title'   => $post_data['post_title'],
+		);
+
+		$request  = new WP_REST_Request( 'POST', '/wp/v2/posts/' . self::$post_id . '/autosaves' );
+		$request->add_header( 'content-type', 'application/json' );
+		$request->set_body( wp_json_encode( $autosave_data ) );
+
+		$response = rest_get_server()->dispatch( $request );
+		$new_data = $response->get_data();
+		$current_post = get_post( $post_id );
+
+		$this->assertEquals( $current_post->ID, $new_data['parent'] );
+
+		// The draft post shouldn't change.
+		$this->assertEquals( $current_post->post_title, $post_data['post_title'] );
+		$this->assertEquals( $current_post->post_content, $post_data['post_content'] );
+		$this->assertEquals( $current_post->post_excerpt, $post_data['post_excerpt'] );
+
+		$autosave_post = wp_get_post_autosave( $post_id );
+
+		// No changes
+		$this->assertEquals( $current_post->post_title, $autosave_post->post_title );
+		$this->assertEquals( $current_post->post_excerpt, $autosave_post->post_excerpt );
+
+		// Has changes
+		$this->assertEquals( $autosave_data['content'], $autosave_post->post_content );
+
+		wp_delete_post( $post_id );
+	}
+
+	public function test_get_additional_field_registration() {
+		$schema = array(
+			'type'        => 'integer',
+			'description' => 'Some integer of mine',
+			'enum'        => array( 1, 2, 3, 4 ),
+			'context'     => array( 'view', 'edit' ),
+		);
+
+		register_rest_field(
+			'post-revision', 'my_custom_int', array(
+				'schema'          => $schema,
+				'get_callback'    => array( $this, 'additional_field_get_callback' ),
+				'update_callback' => array( $this, 'additional_field_update_callback' ),
+			)
+		);
+
+		$request = new WP_REST_Request( 'OPTIONS', '/wp/v2/posts/' . self::$post_id . '/autosaves' );
+
+		$response = rest_get_server()->dispatch( $request );
+		$data     = $response->get_data();
+
+		$this->assertArrayHasKey( 'my_custom_int', $data['schema']['properties'] );
+		$this->assertEquals( $schema, $data['schema']['properties']['my_custom_int'] );
+
+		wp_set_current_user( 1 );
+
+		$request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/autosaves/' . self::$autosave_post_id );
+
+		$response = rest_get_server()->dispatch( $request );
+		$this->assertArrayHasKey( 'my_custom_int', $response->data );
+
+		global $wp_rest_additional_fields;
+		$wp_rest_additional_fields = array();
+	}
+
+	public function additional_field_get_callback( $object ) {
+		return get_post_meta( $object['id'], 'my_custom_int', true );
+	}
+
+	public function additional_field_update_callback( $value, $post ) {
+		update_post_meta( $post->ID, 'my_custom_int', $value );
+	}
+
+	protected function check_get_autosave_response( $response, $autosave ) {
+		if ( $response instanceof WP_REST_Response ) {
+			$links    = $response->get_links();
+			$response = $response->get_data();
+		} else {
+			$this->assertArrayHasKey( '_links', $response );
+			$links = $response['_links'];
+		}
+
+		$this->assertEquals( $autosave->post_author, $response['author'] );
+
+		$rendered_content = apply_filters( 'the_content', $autosave->post_content );
+		$this->assertEquals( $rendered_content, $response['content']['rendered'] );
+
+		$this->assertEquals( mysql_to_rfc3339( $autosave->post_date ), $response['date'] );
+		$this->assertEquals( mysql_to_rfc3339( $autosave->post_date_gmt ), $response['date_gmt'] );
+
+		$rendered_guid = apply_filters( 'get_the_guid', $autosave->guid, $autosave->ID );
+		$this->assertEquals( $rendered_guid, $response['guid']['rendered'] );
+
+		$this->assertEquals( $autosave->ID, $response['id'] );
+		$this->assertEquals( mysql_to_rfc3339( $autosave->post_modified ), $response['modified'] );
+		$this->assertEquals( mysql_to_rfc3339( $autosave->post_modified_gmt ), $response['modified_gmt'] );
+		$this->assertEquals( $autosave->post_name, $response['slug'] );
+
+		$rendered_title = get_the_title( $autosave->ID );
+		$this->assertEquals( $rendered_title, $response['title']['rendered'] );
+
+		$parent            = get_post( $autosave->post_parent );
+		$parent_controller = new WP_REST_Posts_Controller( $parent->post_type );
+		$parent_object     = get_post_type_object( $parent->post_type );
+		$parent_base       = ! empty( $parent_object->rest_base ) ? $parent_object->rest_base : $parent_object->name;
+		$this->assertEquals( rest_url( '/wp/v2/' . $parent_base . '/' . $autosave->post_parent ), $links['parent'][0]['href'] );
+	}
+
+	public function test_get_item_sets_up_postdata() {
+		wp_set_current_user( self::$editor_id );
+		$request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/autosaves/' . self::$autosave_post_id );
+		rest_get_server()->dispatch( $request );
+
+		$post           = get_post();
+		$parent_post_id = wp_is_post_revision( $post->ID );
+
+		$this->assertEquals( $post->ID, self::$autosave_post_id );
+		$this->assertEquals( $parent_post_id, self::$post_id );
+	}
+
+}
diff --git a/tests/phpunit/tests/rest-api/rest-controller.php b/tests/phpunit/tests/rest-api/rest-controller.php
index b9144685ad..88941ec1ee 100644
--- a/tests/phpunit/tests/rest-api/rest-controller.php
+++ b/tests/phpunit/tests/rest-api/rest-controller.php
@@ -213,45 +213,4 @@ class WP_Test_REST_Controller extends WP_Test_REST_TestCase {
 			'someinteger',
 		), $fields );
 	}
-
-	public function test_add_additional_fields_to_object_respects_fields_param() {
-		$controller = new WP_REST_Test_Controller();
-		$request    = new WP_REST_Request( 'GET', '/wp/v2/testroute' );
-		$schema     = $controller->get_item_schema();
-		$field      = 'somefield';
-
-		$listener = new MockAction();
-		$method = 'action';
-
-		register_rest_field(
-			$schema['title'],
-			$field,
-			array(
-				'get_callback' => array( $listener, $method ),
-				'schema'       => array(
-					'type' => 'string',
-				),
-			)
-		);
-
-		$item = array();
-
-		$controller->prepare_item_for_response( $item, $request );
-
-		$first_call_count = $listener->get_call_count( $method );
-
-		$this->assertTrue( $first_call_count > 0 );
-
-		$request->set_param( '_fields', 'somestring' );
-
-		$controller->prepare_item_for_response( $item, $request );
-
-		$this->assertSame( $first_call_count, $listener->get_call_count( $method ) );
-
-		$request->set_param( '_fields', $field );
-
-		$controller->prepare_item_for_response( $item, $request );
-
-		$this->assertTrue( $listener->get_call_count( $method ) > $first_call_count );
-	}
 }
diff --git a/tests/phpunit/tests/rest-api/rest-schema-setup.php b/tests/phpunit/tests/rest-api/rest-schema-setup.php
index e51fcc796d..e19a46d47d 100644
--- a/tests/phpunit/tests/rest-api/rest-schema-setup.php
+++ b/tests/phpunit/tests/rest-api/rest-schema-setup.php
@@ -89,10 +89,14 @@ class WP_Test_REST_Schema_Initialization extends WP_Test_REST_TestCase {
 			'/wp/v2/posts/(?P<id>[\\d]+)',
 			'/wp/v2/posts/(?P<parent>[\\d]+)/revisions',
 			'/wp/v2/posts/(?P<parent>[\\d]+)/revisions/(?P<id>[\\d]+)',
+			'/wp/v2/posts/(?P<parent>[\\d]+)/autosaves',
+			'/wp/v2/posts/(?P<parent>[\\d]+)/autosaves/(?P<id>[\\d]+)',
 			'/wp/v2/pages',
 			'/wp/v2/pages/(?P<id>[\\d]+)',
 			'/wp/v2/pages/(?P<parent>[\\d]+)/revisions',
 			'/wp/v2/pages/(?P<parent>[\\d]+)/revisions/(?P<id>[\\d]+)',
+			'/wp/v2/pages/(?P<parent>[\\d]+)/autosaves',
+			'/wp/v2/pages/(?P<parent>[\\d]+)/autosaves/(?P<id>[\\d]+)',
 			'/wp/v2/media',
 			'/wp/v2/media/(?P<id>[\\d]+)',
 			'/wp/v2/types',
@@ -111,7 +115,6 @@ class WP_Test_REST_Schema_Initialization extends WP_Test_REST_TestCase {
 			'/wp/v2/comments',
 			'/wp/v2/comments/(?P<id>[\\d]+)',
 			'/wp/v2/settings',
-			'/wp/v2/themes',
 		);
 
 		$this->assertEquals( $expected_routes, $routes );
@@ -154,6 +157,16 @@ class WP_Test_REST_Schema_Initialization extends WP_Test_REST_TestCase {
 		$post_revisions = array_values( wp_get_post_revisions( $post_id ) );
 		$post_revision_id = $post_revisions[ count( $post_revisions ) - 1 ]->ID;
 
+		// Create an autosave.
+		wp_create_post_autosave(
+			array(
+				'post_ID'      => $post_id,
+				'post_content' => 'Autosave post content.',
+				'post_type'    => 'post',
+			)
+		);
+
+
 		$page_id = $this->factory->post->create( array(
 			'post_type'      => 'page',
 			'post_name'      => 'restapi-client-fixture-page',
@@ -171,6 +184,15 @@ class WP_Test_REST_Schema_Initialization extends WP_Test_REST_TestCase {
 		$page_revisions = array_values( wp_get_post_revisions( $page_id ) );
 		$page_revision_id = $page_revisions[ count( $page_revisions ) - 1 ]->ID;
 
+		// Create an autosave.
+		wp_create_post_autosave(
+			array(
+				'post_ID'      => $page_id,
+				'post_content' => 'Autosave page content.',
+				'post_type'    => 'page',
+			)
+		);
+
 		$tag_id = $this->factory->tag->create( array(
 			'name'        => 'REST API Client Fixture: Tag',
 			'slug'        => 'restapi-client-fixture-tag',
@@ -256,6 +278,14 @@ class WP_Test_REST_Schema_Initialization extends WP_Test_REST_TestCase {
 				'route' => '/wp/v2/posts/' . $post_id . '/revisions/' . $post_revision_id,
 				'name'  => 'revision',
 			),
+			array(
+				'route' => '/wp/v2/posts/' . $post_id . '/autosaves',
+				'name'  => 'postAutosaves',
+			),
+			array(
+				'route' => '/wp/v2/posts/' . $post_id . '/autosaves/' . $post_revision_id,
+				'name'  => 'autosave',
+			),
 			array(
 				'route' => '/wp/v2/pages',
 				'name'  => 'PagesCollection',
@@ -272,6 +302,14 @@ class WP_Test_REST_Schema_Initialization extends WP_Test_REST_TestCase {
 				'route' => '/wp/v2/pages/'. $page_id . '/revisions/' . $page_revision_id,
 				'name'  => 'pageRevision',
 			),
+			array(
+				'route' => '/wp/v2/pages/' . $page_id . '/autosaves',
+				'name'  => 'pageAutosaves',
+			),
+			array(
+				'route' => '/wp/v2/pages/' . $page_id . '/autosaves/' . $page_revision_id,
+				'name'  => 'pageAutosave',
+			),
 			array(
 				'route' => '/wp/v2/media',
 				'name'  => 'MediaCollection',
diff --git a/tests/phpunit/tests/rest-api/rest-test-controller.php b/tests/phpunit/tests/rest-api/rest-test-controller.php
index a8c3fefe0a..5b90f76e44 100644
--- a/tests/phpunit/tests/rest-api/rest-test-controller.php
+++ b/tests/phpunit/tests/rest-api/rest-test-controller.php
@@ -10,23 +10,9 @@
  * @group restapi
  */
 class WP_REST_Test_Controller extends WP_REST_Controller {
-	/**
-	 * Prepares the item for the REST response.
-	 *
-	 * @param mixed           $item    WordPress representation of the item.
-	 * @param WP_REST_Request $request Request object.
-	 * @return WP_Error|WP_REST_Response Response object on success, or WP_Error object on failure.
-	 */
-	public function prepare_item_for_response( $item, $request ) {
-		$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
-		$item = $this->add_additional_fields_to_object( $item, $request );
-		$item = $this->filter_response_by_context( $item, $context );
-		$response = rest_ensure_response( $item );
-		return $response;
-	}
 
 	/**
-	 * Get the item's schema, conforming to JSON Schema.
+	 * Get the Post type's schema, conforming to JSON Schema
 	 *
 	 * @return array
 	 */
@@ -86,7 +72,7 @@ class WP_REST_Test_Controller extends WP_REST_Controller {
 			),
 		);
 
-		return $this->add_additional_fields_schema( $schema );
+		return $schema;
 	}
 
 }
diff --git a/tests/phpunit/tests/rest-api/rest-themes-controller.php b/tests/phpunit/tests/rest-api/rest-themes-controller.php
deleted file mode 100644
index 590f91ec26..0000000000
--- a/tests/phpunit/tests/rest-api/rest-themes-controller.php
+++ /dev/null
@@ -1,340 +0,0 @@
-<?php
-/**
- * Unit tests covering WP_REST_Themes_Controller functionality.
- *
- * @package WordPress
- * @subpackage REST API
- */
-
-/**
- * @group restapi-themes
- * @group restapi
- */
-class WP_Test_REST_Themes_Controller extends WP_Test_REST_Controller_Testcase {
-	/**
-	 * Subscriber user ID.
-	 *
-	 * @since 5.0.0
-	 *
-	 * @var int $subscriber_id
-	 */
-	protected static $subscriber_id;
-
-	/**
-	 * Contributor user ID.
-	 *
-	 * @since 5.0.0
-	 *
-	 * @var int $contributor_id
-	 */
-	protected static $contributor_id;
-
-	/**
-	 * The current theme object.
-	 *
-	 * @since 5.0.0
-	 *
-	 * @var WP_Theme $current_theme
-	 */
-	protected static $current_theme;
-
-	/**
-	 * The REST API route for themes.
-	 *
-	 * @since 5.0.0
-	 *
-	 * @var string $themes_route
-	 */
-	protected static $themes_route = '/wp/v2/themes';
-
-	/**
-	 * Performs a REST API request for the active theme.
-	 *
-	 * @since 5.0.0
-	 *
-	 * @param string $method Optional. Request method. Default GET.
-	 * @return WP_REST_Response The request's response.
-	 */
-	protected function perform_active_theme_request( $method = 'GET' ) {
-		$request = new WP_REST_Request( $method, self::$themes_route );
-		$request->set_param( 'status', 'active' );
-
-		return rest_get_server()->dispatch( $request );
-	}
-
-	/**
-	 * Check that common properties are included in a response.
-	 *
-	 * @since 5.0.0
-	 *
-	 * @param WP_REST_Response $response Current REST API response.
-	 */
-	protected function check_get_theme_response( $response ) {
-		if ( $response instanceof WP_REST_Response ) {
-			$headers  = $response->get_headers();
-			$response = $response->get_data();
-		} else {
-			$headers = array();
-		}
-
-		$this->assertArrayHasKey( 'X-WP-Total', $headers );
-		$this->assertEquals( 1, $headers['X-WP-Total'] );
-		$this->assertArrayHasKey( 'X-WP-TotalPages', $headers );
-		$this->assertEquals( 1, $headers['X-WP-TotalPages'] );
-	}
-
-	/**
-	 * Set up class test fixtures.
-	 *
-	 * @since 5.0.0
-	 *
-	 * @param WP_UnitTest_Factory $factory WordPress unit test factory.
-	 */
-	public static function wpSetUpBeforeClass( $factory ) {
-		self::$subscriber_id  = $factory->user->create(
-			array(
-				'role' => 'subscriber',
-			)
-		);
-		self::$contributor_id = $factory->user->create(
-			array(
-				'role' => 'contributor',
-			)
-		);
-		self::$current_theme  = wp_get_theme();
-
-		wp_set_current_user( self::$contributor_id );
-	}
-
-	/**
-	 * Clean up test fixtures.
-	 *
-	 * @since 5.0.0
-	 */
-	public static function wpTearDownAfterClass() {
-		self::delete_user( self::$subscriber_id );
-		self::delete_user( self::$contributor_id );
-	}
-
-	/**
-	 * Set up each test method.
-	 *
-	 * @since 5.0.0
-	 */
-	public function setUp() {
-		parent::setUp();
-
-		wp_set_current_user( self::$contributor_id );
-	}
-
-	/**
-	 * Theme routes should be registered correctly.
-	 *
-	 * @ticket 45016
-	 */
-	public function test_register_routes() {
-		$routes = rest_get_server()->get_routes();
-		$this->assertArrayHasKey( self::$themes_route, $routes );
-	}
-
-	/**
-	 * Test retrieving a collection of themes.
-	 *
-	 * @ticket 45016
-	 */
-	public function test_get_items() {
-		$response = self::perform_active_theme_request();
-
-		$this->assertEquals( 200, $response->get_status() );
-		$data = $response->get_data();
-
-		$this->check_get_theme_response( $response );
-		$fields = array(
-			'theme_supports',
-		);
-		$this->assertEqualSets( $fields, array_keys( $data[0] ) );
-	}
-
-	/**
-	 * An error should be returned when the user does not have the edit_posts capability.
-	 *
-	 * @ticket 45016
-	 */
-	public function test_get_items_no_permission() {
-		wp_set_current_user( self::$subscriber_id );
-		$response = self::perform_active_theme_request();
-		$this->assertErrorResponse( 'rest_user_cannot_view', $response, 403 );
-	}
-
-	/**
-	 * Test an item is prepared for the response.
-	 *
-	 * @ticket 45016
-	 */
-	public function test_prepare_item() {
-		$response = self::perform_active_theme_request();
-		$this->assertEquals( 200, $response->get_status() );
-		$this->check_get_theme_response( $response );
-	}
-
-	/**
-	 * Verify the theme schema.
-	 *
-	 * @ticket 45016
-	 */
-	public function test_get_item_schema() {
-		$response   = self::perform_active_theme_request( 'OPTIONS' );
-		$data       = $response->get_data();
-		$properties = $data['schema']['properties'];
-		$this->assertEquals( 1, count( $properties ) );
-		$this->assertArrayHasKey( 'theme_supports', $properties );
-
-		$this->assertEquals( 2, count( $properties['theme_supports']['properties'] ) );
-		$this->assertArrayHasKey( 'formats', $properties['theme_supports']['properties'] );
-		$this->assertArrayHasKey( 'post-thumbnails', $properties['theme_supports']['properties'] );
-	}
-
-	/**
-	 * Should include relevant data in the 'theme_supports' key.
-	 *
-	 * @ticket 45016
-	 */
-	public function test_theme_supports_formats() {
-		remove_theme_support( 'post-formats' );
-		$response = self::perform_active_theme_request();
-		$result   = $response->get_data();
-		$this->assertTrue( isset( $result[0]['theme_supports'] ) );
-		$this->assertTrue( isset( $result[0]['theme_supports']['formats'] ) );
-		$this->assertSame( array( 'standard' ), $result[0]['theme_supports']['formats'] );
-	}
-
-	/**
-	 * Test when a theme only supports some post formats.
-	 *
-	 * @ticket 45016
-	 */
-	public function test_theme_supports_formats_non_default() {
-		add_theme_support( 'post-formats', array( 'aside', 'video' ) );
-		$response = self::perform_active_theme_request();
-		$result   = $response->get_data();
-		$this->assertTrue( isset( $result[0]['theme_supports'] ) );
-		$this->assertTrue( isset( $result[0]['theme_supports']['formats'] ) );
-		$this->assertSame( array( 'standard', 'aside', 'video' ), $result[0]['theme_supports']['formats'] );
-	}
-
-	/**
-	 * Test when a theme does not support post thumbnails.
-	 *
-	 * @ticket 45016
-	 */
-	public function test_theme_supports_post_thumbnails_false() {
-		remove_theme_support( 'post-thumbnails' );
-		$response = self::perform_active_theme_request();
-
-		$result = $response->get_data();
-		$this->assertTrue( isset( $result[0]['theme_supports'] ) );
-		$this->assertTrue( isset( $result[0]['theme_supports']['post-thumbnails'] ) );
-		$this->assertFalse( $result[0]['theme_supports']['post-thumbnails'] );
-	}
-
-	/**
-	 * Test when a theme supports all post thumbnails.
-	 *
-	 * @ticket 45016
-	 */
-	public function test_theme_supports_post_thumbnails_true() {
-		remove_theme_support( 'post-thumbnails' );
-		add_theme_support( 'post-thumbnails' );
-		$response = self::perform_active_theme_request();
-		$result   = $response->get_data();
-		$this->assertTrue( isset( $result[0]['theme_supports'] ) );
-		$this->assertTrue( $result[0]['theme_supports']['post-thumbnails'] );
-	}
-
-	/**
-	 * Test when a theme only supports post thumbnails for certain post types.
-	 *
-	 * @ticket 45016
-	 */
-	public function test_theme_supports_post_thumbnails_array() {
-		remove_theme_support( 'post-thumbnails' );
-		add_theme_support( 'post-thumbnails', array( 'post' ) );
-		$response = self::perform_active_theme_request();
-		$result   = $response->get_data();
-		$this->assertTrue( isset( $result[0]['theme_supports'] ) );
-		$this->assertEquals( array( 'post' ), $result[0]['theme_supports']['post-thumbnails'] );
-	}
-
-	/**
-	 * It should be possible to register custom fields to the endpoint.
-	 *
-	 * @ticket 45016
-	 */
-	public function test_get_additional_field_registration() {
-		$schema = array(
-			'type'        => 'integer',
-			'description' => 'Some integer of mine',
-			'enum'        => array( 1, 2, 3, 4 ),
-		);
-
-		register_rest_field(
-			'theme',
-			'my_custom_int',
-			array(
-				'schema'       => $schema,
-				'get_callback' => array( $this, 'additional_field_get_callback' ),
-			)
-		);
-
-		$response = self::perform_active_theme_request( 'OPTIONS' );
-		$data     = $response->get_data();
-
-		$this->assertArrayHasKey( 'my_custom_int', $data['schema']['properties'] );
-		$this->assertEquals( $schema, $data['schema']['properties']['my_custom_int'] );
-
-		$response = self::perform_active_theme_request( 'GET' );
-		$data     = $response->get_data();
-		$this->assertArrayHasKey( 'my_custom_int', $data[0] );
-		$this->assertSame( 2, $data[0]['my_custom_int'] );
-
-		global $wp_rest_additional_fields;
-		$wp_rest_additional_fields = array();
-	}
-
-	/**
-	 * Return a value for the custom field.
-	 *
-	 * @since 5.0.0
-	 *
-	 * @param array $theme Theme data array.
-	 * @return int Additional field value.
-	 */
-	public function additional_field_get_callback( $theme ) {
-		return 2;
-	}
-
-	/**
-	 * The create_item() method does not exist for themes.
-	 */
-	public function test_create_item() {}
-
-	/**
-	 * The update_item() method does not exist for themes.
-	 */
-	public function test_update_item() {}
-
-	/**
-	 * The get_item() method does not exist for themes.
-	 */
-	public function test_get_item() {}
-
-	/**
-	 * The delete_item() method does not exist for themes.
-	 */
-	public function test_delete_item() {}
-
-	/**
-	 * Context is not supported for themes.
-	 */
-	public function test_context_param() {}
-}
diff --git a/tests/qunit/fixtures/wp-api-generated.js b/tests/qunit/fixtures/wp-api-generated.js
index 6b9d530b46..524f31e5be 100644
--- a/tests/qunit/fixtures/wp-api-generated.js
+++ b/tests/qunit/fixtures/wp-api-generated.js
@@ -850,6 +850,200 @@ mockedApiResponse.Schema = {
                 }
             ]
         },
+        "/wp/v2/posts/(?P<parent>[\\d]+)/autosaves": {
+            "namespace": "wp/v2",
+            "methods": [
+                "GET",
+                "POST"
+            ],
+            "endpoints": [
+                {
+                    "methods": [
+                        "GET"
+                    ],
+                    "args": {
+                        "parent": {
+                            "required": false,
+                            "description": "The ID for the parent of the object.",
+                            "type": "integer"
+                        },
+                        "context": {
+                            "required": false,
+                            "default": "view",
+                            "enum": [
+                                "view",
+                                "embed",
+                                "edit"
+                            ],
+                            "description": "Scope under which the request is made; determines fields present in response.",
+                            "type": "string"
+                        },
+                        "page": {
+                            "required": false,
+                            "default": 1,
+                            "description": "Current page of the collection.",
+                            "type": "integer"
+                        },
+                        "per_page": {
+                            "required": false,
+                            "description": "Maximum number of items to be returned in result set.",
+                            "type": "integer"
+                        },
+                        "search": {
+                            "required": false,
+                            "description": "Limit results to those matching a string.",
+                            "type": "string"
+                        },
+                        "exclude": {
+                            "required": false,
+                            "default": [],
+                            "description": "Ensure result set excludes specific IDs.",
+                            "type": "array",
+                            "items": {
+                                "type": "integer"
+                            }
+                        },
+                        "include": {
+                            "required": false,
+                            "default": [],
+                            "description": "Limit result set to specific IDs.",
+                            "type": "array",
+                            "items": {
+                                "type": "integer"
+                            }
+                        },
+                        "offset": {
+                            "required": false,
+                            "description": "Offset the result set by a specific number of items.",
+                            "type": "integer"
+                        },
+                        "order": {
+                            "required": false,
+                            "default": "desc",
+                            "enum": [
+                                "asc",
+                                "desc"
+                            ],
+                            "description": "Order sort attribute ascending or descending.",
+                            "type": "string"
+                        },
+                        "orderby": {
+                            "required": false,
+                            "default": "date",
+                            "enum": [
+                                "date",
+                                "id",
+                                "include",
+                                "relevance",
+                                "slug",
+                                "include_slugs",
+                                "title"
+                            ],
+                            "description": "Sort collection by object attribute.",
+                            "type": "string"
+                        }
+                    }
+                },
+                {
+                    "methods": [
+                        "POST"
+                    ],
+                    "args": {
+                        "parent": {
+                            "required": false,
+                            "description": "The ID for the parent of the object.",
+                            "type": "integer"
+                        },
+                        "author": {
+                            "required": false,
+                            "description": "The ID for the author of the object.",
+                            "type": "integer"
+                        },
+                        "date": {
+                            "required": false,
+                            "description": "The date the object was published, in the site's timezone.",
+                            "type": "string"
+                        },
+                        "date_gmt": {
+                            "required": false,
+                            "description": "The date the object was published, as GMT.",
+                            "type": "string"
+                        },
+                        "id": {
+                            "required": false,
+                            "description": "Unique identifier for the object.",
+                            "type": "integer"
+                        },
+                        "modified": {
+                            "required": false,
+                            "description": "The date the object was last modified, in the site's timezone.",
+                            "type": "string"
+                        },
+                        "modified_gmt": {
+                            "required": false,
+                            "description": "The date the object was last modified, as GMT.",
+                            "type": "string"
+                        },
+                        "slug": {
+                            "required": false,
+                            "description": "An alphanumeric identifier for the object unique to its type.",
+                            "type": "string"
+                        },
+                        "title": {
+                            "required": false,
+                            "description": "The title for the object.",
+                            "type": "object"
+                        },
+                        "content": {
+                            "required": false,
+                            "description": "The content for the object.",
+                            "type": "object"
+                        },
+                        "excerpt": {
+                            "required": false,
+                            "description": "The excerpt for the object.",
+                            "type": "object"
+                        }
+                    }
+                }
+            ]
+        },
+        "/wp/v2/posts/(?P<parent>[\\d]+)/autosaves/(?P<id>[\\d]+)": {
+            "namespace": "wp/v2",
+            "methods": [
+                "GET"
+            ],
+            "endpoints": [
+                {
+                    "methods": [
+                        "GET"
+                    ],
+                    "args": {
+                        "parent": {
+                            "required": false,
+                            "description": "The ID for the parent of the object.",
+                            "type": "integer"
+                        },
+                        "id": {
+                            "required": false,
+                            "description": "The ID for the object.",
+                            "type": "integer"
+                        },
+                        "context": {
+                            "required": false,
+                            "default": "view",
+                            "enum": [
+                                "view",
+                                "embed",
+                                "edit"
+                            ],
+                            "description": "Scope under which the request is made; determines fields present in response.",
+                            "type": "string"
+                        }
+                    }
+                }
+            ]
+        },
         "/wp/v2/pages": {
             "namespace": "wp/v2",
             "methods": [
@@ -1294,17 +1488,173 @@ mockedApiResponse.Schema = {
                         "force": {
                             "required": false,
                             "default": false,
-                            "description": "Whether to bypass trash and force deletion.",
+                            "description": "Whether to bypass trash and force deletion.",
+                            "type": "boolean"
+                        }
+                    }
+                }
+            ]
+        },
+        "/wp/v2/pages/(?P<parent>[\\d]+)/revisions": {
+            "namespace": "wp/v2",
+            "methods": [
+                "GET"
+            ],
+            "endpoints": [
+                {
+                    "methods": [
+                        "GET"
+                    ],
+                    "args": {
+                        "parent": {
+                            "required": false,
+                            "description": "The ID for the parent of the object.",
+                            "type": "integer"
+                        },
+                        "context": {
+                            "required": false,
+                            "default": "view",
+                            "enum": [
+                                "view",
+                                "embed",
+                                "edit"
+                            ],
+                            "description": "Scope under which the request is made; determines fields present in response.",
+                            "type": "string"
+                        },
+                        "page": {
+                            "required": false,
+                            "default": 1,
+                            "description": "Current page of the collection.",
+                            "type": "integer"
+                        },
+                        "per_page": {
+                            "required": false,
+                            "description": "Maximum number of items to be returned in result set.",
+                            "type": "integer"
+                        },
+                        "search": {
+                            "required": false,
+                            "description": "Limit results to those matching a string.",
+                            "type": "string"
+                        },
+                        "exclude": {
+                            "required": false,
+                            "default": [],
+                            "description": "Ensure result set excludes specific IDs.",
+                            "type": "array",
+                            "items": {
+                                "type": "integer"
+                            }
+                        },
+                        "include": {
+                            "required": false,
+                            "default": [],
+                            "description": "Limit result set to specific IDs.",
+                            "type": "array",
+                            "items": {
+                                "type": "integer"
+                            }
+                        },
+                        "offset": {
+                            "required": false,
+                            "description": "Offset the result set by a specific number of items.",
+                            "type": "integer"
+                        },
+                        "order": {
+                            "required": false,
+                            "default": "desc",
+                            "enum": [
+                                "asc",
+                                "desc"
+                            ],
+                            "description": "Order sort attribute ascending or descending.",
+                            "type": "string"
+                        },
+                        "orderby": {
+                            "required": false,
+                            "default": "date",
+                            "enum": [
+                                "date",
+                                "id",
+                                "include",
+                                "relevance",
+                                "slug",
+                                "include_slugs",
+                                "title"
+                            ],
+                            "description": "Sort collection by object attribute.",
+                            "type": "string"
+                        }
+                    }
+                }
+            ]
+        },
+        "/wp/v2/pages/(?P<parent>[\\d]+)/revisions/(?P<id>[\\d]+)": {
+            "namespace": "wp/v2",
+            "methods": [
+                "GET",
+                "DELETE"
+            ],
+            "endpoints": [
+                {
+                    "methods": [
+                        "GET"
+                    ],
+                    "args": {
+                        "parent": {
+                            "required": false,
+                            "description": "The ID for the parent of the object.",
+                            "type": "integer"
+                        },
+                        "id": {
+                            "required": false,
+                            "description": "Unique identifier for the object.",
+                            "type": "integer"
+                        },
+                        "context": {
+                            "required": false,
+                            "default": "view",
+                            "enum": [
+                                "view",
+                                "embed",
+                                "edit"
+                            ],
+                            "description": "Scope under which the request is made; determines fields present in response.",
+                            "type": "string"
+                        }
+                    }
+                },
+                {
+                    "methods": [
+                        "DELETE"
+                    ],
+                    "args": {
+                        "parent": {
+                            "required": false,
+                            "description": "The ID for the parent of the object.",
+                            "type": "integer"
+                        },
+                        "id": {
+                            "required": false,
+                            "description": "Unique identifier for the object.",
+                            "type": "integer"
+                        },
+                        "force": {
+                            "required": false,
+                            "default": false,
+                            "description": "Required to be true, as revisions do not support trashing.",
                             "type": "boolean"
                         }
                     }
                 }
             ]
         },
-        "/wp/v2/pages/(?P<parent>[\\d]+)/revisions": {
+        "/wp/v2/pages/(?P<parent>[\\d]+)/autosaves": {
             "namespace": "wp/v2",
             "methods": [
-                "GET"
+                "GET",
+                "POST"
             ],
             "endpoints": [
                 {
@@ -1393,19 +1743,10 @@ mockedApiResponse.Schema = {
                             "type": "string"
                         }
                     }
-                }
-            ]
-        },
-        "/wp/v2/pages/(?P<parent>[\\d]+)/revisions/(?P<id>[\\d]+)": {
-            "namespace": "wp/v2",
-            "methods": [
-                "GET",
-                "DELETE"
-            ],
-            "endpoints": [
+                },
                 {
                     "methods": [
-                        "GET"
+                        "POST"
                     ],
                     "args": {
                         "parent": {
@@ -1413,27 +1754,69 @@ mockedApiResponse.Schema = {
                             "description": "The ID for the parent of the object.",
                             "type": "integer"
                         },
+                        "author": {
+                            "required": false,
+                            "description": "The ID for the author of the object.",
+                            "type": "integer"
+                        },
+                        "date": {
+                            "required": false,
+                            "description": "The date the object was published, in the site's timezone.",
+                            "type": "string"
+                        },
+                        "date_gmt": {
+                            "required": false,
+                            "description": "The date the object was published, as GMT.",
+                            "type": "string"
+                        },
                         "id": {
                             "required": false,
                             "description": "Unique identifier for the object.",
                             "type": "integer"
                         },
-                        "context": {
+                        "modified": {
                             "required": false,
-                            "default": "view",
-                            "enum": [
-                                "view",
-                                "embed",
-                                "edit"
-                            ],
-                            "description": "Scope under which the request is made; determines fields present in response.",
+                            "description": "The date the object was last modified, in the site's timezone.",
+                            "type": "string"
+                        },
+                        "modified_gmt": {
+                            "required": false,
+                            "description": "The date the object was last modified, as GMT.",
                             "type": "string"
+                        },
+                        "slug": {
+                            "required": false,
+                            "description": "An alphanumeric identifier for the object unique to its type.",
+                            "type": "string"
+                        },
+                        "title": {
+                            "required": false,
+                            "description": "The title for the object.",
+                            "type": "object"
+                        },
+                        "content": {
+                            "required": false,
+                            "description": "The content for the object.",
+                            "type": "object"
+                        },
+                        "excerpt": {
+                            "required": false,
+                            "description": "The excerpt for the object.",
+                            "type": "object"
                         }
                     }
-                },
+                }
+            ]
+        },
+        "/wp/v2/pages/(?P<parent>[\\d]+)/autosaves/(?P<id>[\\d]+)": {
+            "namespace": "wp/v2",
+            "methods": [
+                "GET"
+            ],
+            "endpoints": [
                 {
                     "methods": [
-                        "DELETE"
+                        "GET"
                     ],
                     "args": {
                         "parent": {
@@ -1443,14 +1826,19 @@ mockedApiResponse.Schema = {
                         },
                         "id": {
                             "required": false,
-                            "description": "Unique identifier for the object.",
+                            "description": "The ID for the object.",
                             "type": "integer"
                         },
-                        "force": {
+                        "context": {
                             "required": false,
-                            "default": false,
-                            "description": "Required to be true, as revisions do not support trashing.",
-                            "type": "boolean"
+                            "default": "view",
+                            "enum": [
+                                "view",
+                                "embed",
+                                "edit"
+                            ],
+                            "description": "Scope under which the request is made; determines fields present in response.",
+                            "type": "string"
                         }
                     }
                 }
@@ -3517,57 +3905,6 @@ mockedApiResponse.Schema = {
             "_links": {
                 "self": "http://example.org/index.php?rest_route=/wp/v2/settings"
             }
-        },
-        "/wp/v2/themes": {
-            "namespace": "wp/v2",
-            "methods": [
-                "GET"
-            ],
-            "endpoints": [
-                {
-                    "methods": [
-                        "GET"
-                    ],
-                    "args": {
-                        "context": {
-                            "required": false,
-                            "description": "Scope under which the request is made; determines fields present in response.",
-                            "type": "string"
-                        },
-                        "page": {
-                            "required": false,
-                            "default": 1,
-                            "description": "Current page of the collection.",
-                            "type": "integer"
-                        },
-                        "per_page": {
-                            "required": false,
-                            "default": 10,
-                            "description": "Maximum number of items to be returned in result set.",
-                            "type": "integer"
-                        },
-                        "search": {
-                            "required": false,
-                            "description": "Limit results to those matching a string.",
-                            "type": "string"
-                        },
-                        "status": {
-                            "required": true,
-                            "description": "Limit result set to themes assigned one or more statuses.",
-                            "type": "array",
-                            "items": {
-                                "enum": [
-                                    "active"
-                                ],
-                                "type": "string"
-                            }
-                        }
-                    }
-                }
-            ],
-            "_links": {
-                "self": "http://example.org/index.php?rest_route=/wp/v2/themes"
-            }
         }
     }
 };
@@ -3774,7 +4111,7 @@ mockedApiResponse.PostsCollection = [
             ],
             "version-history": [
                 {
-                    "count": 1,
+                    "count": 2,
                     "href": "http://example.org/index.php?rest_route=/wp/v2/posts/4/revisions"
                 }
             ],
@@ -3865,6 +4202,35 @@ mockedApiResponse.postRevisions = [
         "guid": {
             "rendered": "http://example.org/?p=5"
         },
+        "title": {
+            "rendered": ""
+        },
+        "content": {
+            "rendered": "<p>Autosave post content.</p>\n"
+        },
+        "excerpt": {
+            "rendered": ""
+        },
+        "_links": {
+            "parent": [
+                {
+                    "href": "http://example.org/index.php?rest_route=/wp/v2/posts/4"
+                }
+            ]
+        }
+    },
+    {
+        "author": 67,
+        "date": "2017-02-14T00:00:00",
+        "date_gmt": "2017-02-14T00:00:00",
+        "id": 456,
+        "modified": "2017-02-14T00:00:00",
+        "modified_gmt": "2017-02-14T00:00:00",
+        "parent": 455,
+        "slug": "455-revision-v1",
+        "guid": {
+            "rendered": "http://example.org/?p=456"
+        },
         "title": {
             "rendered": "REST API Client Fixture: Post"
         },
@@ -3877,7 +4243,7 @@ mockedApiResponse.postRevisions = [
         "_links": {
             "parent": [
                 {
-                    "href": "http://example.org/index.php?rest_route=/wp/v2/posts/4"
+                    "href": "http://example.org/index.php?rest_route=/wp/v2/posts/455"
                 }
             ]
         }
@@ -3907,6 +4273,61 @@ mockedApiResponse.revision = {
     }
 };
 
+mockedApiResponse.postAutosaves = [
+    {
+        "author": 67,
+        "date": "2017-02-14T00:00:00",
+        "date_gmt": "2017-02-14T00:00:00",
+        "id": 457,
+        "modified": "2017-02-14T00:00:00",
+        "modified_gmt": "2017-02-14T00:00:00",
+        "parent": 455,
+        "slug": "455-autosave-v1",
+        "guid": {
+            "rendered": "http://example.org/?p=457"
+        },
+        "title": {
+            "rendered": ""
+        },
+        "content": {
+            "rendered": "<p>Autosave post content.</p>\n"
+        },
+        "excerpt": {
+            "rendered": ""
+        },
+        "_links": {
+            "parent": [
+                {
+                    "href": "http://example.org/index.php?rest_route=/wp/v2/posts/455"
+                }
+            ]
+        }
+    }
+];
+
+mockedApiResponse.autosave = {
+    "author": 67,
+    "date": "2017-02-14T00:00:00",
+    "date_gmt": "2017-02-14T00:00:00",
+    "id": 457,
+    "modified": "2017-02-14T00:00:00",
+    "modified_gmt": "2017-02-14T00:00:00",
+    "parent": 455,
+    "slug": "455-autosave-v1",
+    "guid": {
+        "rendered": "http://example.org/?p=457"
+    },
+    "title": {
+        "rendered": ""
+    },
+    "content": {
+        "rendered": "<p>Autosave post content.</p>\n"
+    },
+    "excerpt": {
+        "rendered": ""
+    }
+};
+
 mockedApiResponse.PagesCollection = [
     {
         "id": 6,
@@ -3966,7 +4387,7 @@ mockedApiResponse.PagesCollection = [
             ],
             "version-history": [
                 {
-                    "count": 1,
+                    "count": 2,
                     "href": "http://example.org/index.php?rest_route=/wp/v2/pages/6/revisions"
                 }
             ],
@@ -4041,6 +4462,35 @@ mockedApiResponse.pageRevisions = [
         "guid": {
             "rendered": "http://example.org/?p=7"
         },
+        "title": {
+            "rendered": ""
+        },
+        "content": {
+            "rendered": "<p>Autosave page content.</p>\n"
+        },
+        "excerpt": {
+            "rendered": ""
+        },
+        "_links": {
+            "parent": [
+                {
+                    "href": "http://example.org/index.php?rest_route=/wp/v2/pages/6"
+                }
+            ]
+        }
+    },
+    {
+        "author": 67,
+        "date": "2017-02-14T00:00:00",
+        "date_gmt": "2017-02-14T00:00:00",
+        "id": 459,
+        "modified": "2017-02-14T00:00:00",
+        "modified_gmt": "2017-02-14T00:00:00",
+        "parent": 458,
+        "slug": "458-revision-v1",
+        "guid": {
+            "rendered": "http://example.org/?p=459"
+        },
         "title": {
             "rendered": "REST API Client Fixture: Page"
         },
@@ -4053,7 +4503,7 @@ mockedApiResponse.pageRevisions = [
         "_links": {
             "parent": [
                 {
-                    "href": "http://example.org/index.php?rest_route=/wp/v2/pages/6"
+                    "href": "http://example.org/index.php?rest_route=/wp/v2/pages/458"
                 }
             ]
         }
@@ -4083,6 +4533,61 @@ mockedApiResponse.pageRevision = {
     }
 };
 
+mockedApiResponse.pageAutosaves = [
+    {
+        "author": 67,
+        "date": "2017-02-14T00:00:00",
+        "date_gmt": "2017-02-14T00:00:00",
+        "id": 460,
+        "modified": "2017-02-14T00:00:00",
+        "modified_gmt": "2017-02-14T00:00:00",
+        "parent": 458,
+        "slug": "458-autosave-v1",
+        "guid": {
+            "rendered": "http://example.org/?p=460"
+        },
+        "title": {
+            "rendered": ""
+        },
+        "content": {
+            "rendered": "<p>Autosave page content.</p>\n"
+        },
+        "excerpt": {
+            "rendered": ""
+        },
+        "_links": {
+            "parent": [
+                {
+                    "href": "http://example.org/index.php?rest_route=/wp/v2/pages/458"
+                }
+            ]
+        }
+    }
+];
+
+mockedApiResponse.pageAutosave = {
+    "author": 67,
+    "date": "2017-02-14T00:00:00",
+    "date_gmt": "2017-02-14T00:00:00",
+    "id": 460,
+    "modified": "2017-02-14T00:00:00",
+    "modified_gmt": "2017-02-14T00:00:00",
+    "parent": 458,
+    "slug": "458-autosave-v1",
+    "guid": {
+        "rendered": "http://example.org/?p=460"
+    },
+    "title": {
+        "rendered": ""
+    },
+    "content": {
+        "rendered": "<p>Autosave page content.</p>\n"
+    },
+    "excerpt": {
+        "rendered": ""
+    }
+};
+
 mockedApiResponse.MediaCollection = [
     {
         "id": 8,
