diff --git Gruntfile.js Gruntfile.js
index 061724429..542ac1a6f 100644
--- Gruntfile.js
+++ Gruntfile.js
@@ -190,7 +190,8 @@ module.exports = function( grunt ) {
 			}
 		},
 		clean: {
-			all: [ BUILD_DIR ]
+			all: [ BUILD_DIR ],
+			bp_rest: [ BUILD_DIR + 'bp-rest/' ]
 		},
 		copy: {
 			files: {
@@ -209,6 +210,32 @@ module.exports = function( grunt ) {
 						src: ['composer.json']
 					}
 				]
+			},
+			bp_rest_components: {
+				cwd: BUILD_DIR + 'bp-rest/includes/',
+				dest: BUILD_DIR,
+				dot: true,
+				expand: true,
+				src: ['**/bp-activity/**', '**/bp-blogs/**', '**/bp-friends/**', '**/bp-groups/**', '**/bp-members/**', '**/bp-messages/**', '**/bp-notifications/**', '**/bp-settings/**', '**/bp-xprofile/**'],
+				options: {
+					process : function( content ) {
+						return content.replace( /\@since 0\.1\.0/g, '@since 5.0.0' );
+					}
+				}
+			},
+			bp_rest_core: {
+				cwd: BUILD_DIR + 'bp-rest/includes/',
+				dest: BUILD_DIR + 'bp-core/classes/',
+				dot: true,
+				expand: true,
+				flatten: true,
+				filter: 'isFile',
+				src: ['**', '!functions.php', '!**/bp-activity/**', '!**/bp-blogs/**', '!**/bp-friends/**', '!**/bp-groups/**', '!**/bp-members/**', '!**/bp-messages/**', '!**/bp-notifications/**', '!**/bp-settings/**', '!**/bp-xprofile/**'],
+				options: {
+					process : function( content ) {
+						return content.replace( /\@since 0\.1\.0/g, '@since 5.0.0' );
+					}
+				}
 			}
 		},
 		uglify: {
@@ -300,6 +327,11 @@ module.exports = function( grunt ) {
 			phpcompat: {
 				command: './vendor/bin/phpcs -p --standard=PHPCompatibilityWP --extensions=php --runtime-set testVersion 5.3- src tests',
 				stdout: true
+			},
+			rest_api: {
+				command: 'svn export --force https://github.com/buddypress/BP-REST.git/trunk bp-rest',
+				cwd: BUILD_DIR,
+				stdout: false
 			}
 		},
 		jsvalidate:{
@@ -331,13 +363,13 @@ module.exports = function( grunt ) {
 		}
 	});
 
-
 	/**
 	 * Register tasks.
 	 */
 	grunt.registerTask( 'src',     ['checkDependencies', 'jsvalidate:src', 'jshint', 'stylelint', 'sass', 'postcss', 'rtlcss'] );
 	grunt.registerTask( 'commit',  ['src', 'checktextdomain', 'imagemin', 'phplint', 'exec:phpcompat'] );
-	grunt.registerTask( 'build',   ['commit', 'clean:all', 'copy:files', 'uglify', 'jsvalidate:build', 'cssmin', 'makepot', 'exec:bpdefault', 'exec:cli'] );
+	grunt.registerTask( 'bp_rest', [ 'exec:rest_api', 'copy:bp_rest_components', 'copy:bp_rest_core', 'clean:bp_rest' ] );
+	grunt.registerTask( 'build',   ['commit', 'clean:all', 'copy:files', 'uglify', 'jsvalidate:build', 'cssmin', 'bp_rest', 'makepot', 'exec:bpdefault', 'exec:cli'] );
 	grunt.registerTask( 'release', ['build'] );
 
 	// Testing tasks.
diff --git src/bp-activity/classes/class-bp-activity-component.php src/bp-activity/classes/class-bp-activity-component.php
index 1d882f213..a362a358c 100644
--- src/bp-activity/classes/class-bp-activity-component.php
+++ src/bp-activity/classes/class-bp-activity-component.php
@@ -456,4 +456,16 @@ class BP_Activity_Component extends BP_Component {
 
 		parent::setup_cache_groups();
 	}
+
+	/**
+	 * Init the BP REST API.
+	 *
+	 * @since 5.0.0
+	 */
+	public function rest_api_init() {
+		$controller = new BP_REST_Activity_Endpoint();
+		$controller->register_routes();
+
+		parent::rest_api_init();
+	}
 }
diff --git src/bp-core/bp-core-rest-api.php src/bp-core/bp-core-rest-api.php
index d4ad8319c..46ac80b00 100644
--- src/bp-core/bp-core-rest-api.php
+++ src/bp-core/bp-core-rest-api.php
@@ -21,6 +21,23 @@ function bp_rest_is_plugin_active() {
     return (bool) has_action( 'bp_rest_api_init', 'bp_rest', 5 );
 }
 
+/**
+ * Should we use the REST Endpoints of built BuddyPress?
+ *
+ * If the BP REST plugin is active, it overrides BuddyPress REST enpoints.
+ * This allows us to carry on maintaining all the BP REST API endpoints from
+ * the BP REST plugin on GitHub.
+ *
+ * @since 5.0.0
+ *
+ * @return bool Whether to use the REST Endpoints of built BuddyPress.
+ */
+function bp_rest_in_buddypress() {
+    $is_src = defined( 'BP_SOURCE_SUBDIRECTORY' ) && BP_SOURCE_SUBDIRECTORY === 'src';
+
+    return ! $is_src && ! bp_rest_is_plugin_active();
+}
+
 /**
  * Check the availability of the BP REST API.
  *
@@ -29,6 +46,7 @@ function bp_rest_is_plugin_active() {
  * @return boolean True if the BP REST API is available. False otherwise.
  */
 function bp_rest_api_is_available() {
+
     /**
      * Filter here to disable the BP REST API.
      *
@@ -38,7 +56,7 @@ function bp_rest_api_is_available() {
      *
      * @param boolean $value True if the BP REST API is available. False otherwise.
      */
-    return apply_filters( 'bp_rest_api_is_available', function_exists( 'create_initial_rest_routes' ) && bp_rest_is_plugin_active() );
+    return apply_filters( 'bp_rest_api_is_available', function_exists( 'create_initial_rest_routes' ) && bp_rest_in_buddypress() ) || bp_rest_is_plugin_active();
 }
 
 /**
@@ -75,3 +93,300 @@ function bp_rest_api_register_request_script() {
     );
 }
 add_action( 'bp_init', 'bp_rest_api_register_request_script' );
+
+/**
+ * BuddyPress REST API namespace.
+ *
+ * @since 5.0.0
+ *
+ * @return string
+ */
+function bp_rest_namespace() {
+
+	/**
+	 * Filter API namespace.
+	 *
+	 * @since 5.0.0
+	 *
+	 * @param string $namespace BuddyPress core namespace.
+	 */
+	return apply_filters( 'bp_rest_namespace', 'buddypress' );
+}
+
+/**
+ * BuddyPress REST API version.
+ *
+ * @since 5.0.0
+ *
+ * @return string
+ */
+function bp_rest_version() {
+
+	/**
+	 * Filter API version.
+	 *
+	 * @since 5.0.0
+	 *
+	 * @param string $version BuddyPress core version.
+	 */
+	return apply_filters( 'bp_rest_version', 'v1' );
+}
+
+/**
+ * Get user URL.
+ *
+ * @since 5.0.0
+ *
+ * @param  int $user_id User ID.
+ * @return string
+ */
+function bp_rest_get_user_url( $user_id ) {
+	return sprintf(
+		'/%s/%s/members/%d',
+		bp_rest_namespace(),
+		bp_rest_version(),
+		$user_id
+	);
+}
+
+/**
+ * Set headers to let the Client Script be aware of the pagination.
+ *
+ * @since 5.0.0
+ *
+ * @param  WP_REST_Response $response The response data.
+ * @param  integer          $total    The total number of found items.
+ * @param  integer          $per_page The number of items per page of results.
+ * @return WP_REST_Response $response The response data.
+ */
+function bp_rest_response_add_total_headers( WP_REST_Response $response, $total = 0, $per_page = 0 ) {
+	if ( ! $total || ! $per_page ) {
+		return $response;
+	}
+
+	$total_items = (int) $total;
+	$max_pages   = ceil( $total_items / (int) $per_page );
+
+	$response->header( 'X-WP-Total', $total_items );
+	$response->header( 'X-WP-TotalPages', (int) $max_pages );
+
+	return $response;
+}
+
+/**
+ * Convert the input date to RFC3339 format.
+ *
+ * @since 5.0.0
+ *
+ * @param string      $date_gmt Date GMT format.
+ * @param string|null $date     Optional. Date object.
+ * @return string|null ISO8601/RFC3339 formatted datetime.
+ */
+function bp_rest_prepare_date_response( $date_gmt, $date = null ) {
+	if ( isset( $date ) ) {
+		return mysql_to_rfc3339( $date );
+	}
+
+	if ( '0000-00-00 00:00:00' === $date_gmt ) {
+		return null;
+	}
+
+	return mysql_to_rfc3339( $date_gmt );
+}
+
+/**
+ * Clean up member_type input.
+ *
+ * @since 5.0.0
+ *
+ * @param string $value Comma-separated list of group types.
+ * @return array|null
+ */
+function bp_rest_sanitize_member_types( $value ) {
+	if ( empty( $value ) ) {
+		return $value;
+	}
+
+	$types              = explode( ',', $value );
+	$registered_types   = bp_get_member_types();
+	$registered_types[] = 'any';
+	$valid_types        = array_intersect( $types, $registered_types );
+
+	return ( ! empty( $valid_types ) ) ? $valid_types : null;
+}
+
+/**
+ * Validate member_type input.
+ *
+ * @since 5.0.0
+ *
+ * @param  mixed $value Mixed value.
+ * @return WP_Error|boolean
+ */
+function bp_rest_validate_member_types( $value ) {
+	if ( empty( $value ) ) {
+		return true;
+	}
+
+	$types            = explode( ',', $value );
+	$registered_types = bp_get_member_types();
+
+	// Add the special value.
+	$registered_types[] = 'any';
+	foreach ( $types as $type ) {
+		if ( ! in_array( $type, $registered_types, true ) ) {
+			return new WP_Error(
+				'bp_rest_invalid_group_type',
+				sprintf(
+					/* translators: %1$s and %2$s is replaced with the registered type(s) */
+					__( 'The member type you provided, %$1s, is not one of %$2s.', 'buddypress' ),
+					$type,
+					implode( ', ', $registered_types )
+				)
+			);
+		}
+	}
+}
+
+/**
+ * Clean up group_type input.
+ *
+ * @since 5.0.0
+ *
+ * @param string $value Comma-separated list of group types.
+ * @return array|null
+ */
+function bp_rest_sanitize_group_types( $value ) {
+	if ( empty( $value ) ) {
+		return null;
+	}
+
+	$types       = explode( ',', $value );
+	$valid_types = array_intersect( $types, bp_groups_get_group_types() );
+
+	return empty( $valid_types ) ? null : $valid_types;
+}
+
+/**
+ * Validate group_type input.
+ *
+ * @since 5.0.0
+ *
+ * @param  mixed $value Mixed value.
+ * @return WP_Error|bool
+ */
+function bp_rest_validate_group_types( $value ) {
+	if ( empty( $value ) ) {
+		return true;
+	}
+
+	$types            = explode( ',', $value );
+	$registered_types = bp_groups_get_group_types();
+	foreach ( $types as $type ) {
+		if ( ! in_array( $type, $registered_types, true ) ) {
+			return new WP_Error(
+				'bp_rest_invalid_group_type',
+				sprintf(
+					/* translators: %1$s and %2$s is replaced with the registered types */
+					__( 'The group type you provided, %1$s, is not one of %2$s.', 'buddypress' ),
+					$type,
+					implode( ', ', $registered_types )
+				)
+			);
+		}
+	}
+}
+
+/**
+ * Clean up an array, comma- or space-separated list of strings.
+ *
+ * @since 5.0.0
+ *
+ * @param array|string $list List of strings.
+ * @return array Sanitized array of strings.
+ */
+function bp_rest_sanitize_string_list( $list ) {
+	if ( ! is_array( $list ) ) {
+		$list = preg_split( '/[\s,]+/', $list );
+	}
+
+	return array_unique( array_map( 'sanitize_text_field', $list ) );
+}
+
+/**
+ * Get the user object, if the ID is valid.
+ *
+ * @since 5.0.0
+ *
+ * @param int $user_id Supplied user ID.
+ * @return WP_User|boolean
+ */
+function bp_rest_get_user( $user_id ) {
+	if ( (int) $user_id <= 0 ) {
+		return false;
+	}
+
+	$user = get_userdata( (int) $user_id );
+	if ( empty( $user ) || ! $user->exists() ) {
+		return false;
+	}
+
+	return $user;
+}
+
+/**
+ * Registers a new field on an existing BuddyPress object.
+ *
+ * @since 5.0.0
+ *
+ * @param string $component_id The name of the *active* component (eg: `activity`, `groups`, `xprofile`).
+ *                             Required.
+ * @param string $attribute    The attribute name. Required.
+ * @param array  $args {
+ *     Optional. An array of arguments used to handle the registered field.
+ *     @see `register_rest_field()` for a full description.
+ * }
+ * @param string $object_type  The xProfile object type to get. This parameter is only required for
+ *                             the Extended Profiles component. Not used for all other components.
+ *                             Possible values are `data`, `field` or `group`.
+ * @return bool                True if the field has been registered successfully. False otherwise.
+ */
+function bp_rest_register_field( $component_id, $attribute, $args = array(), $object_type = '' ) {
+	$registered_fields = false;
+
+	if ( ! $component_id || ! bp_is_active( $component_id ) || ! $attribute ) {
+		return $registered_fields;
+	}
+
+	// Use the `bp_` prefix as we're using a WordPress global used for Post Types.
+	$field_name = 'bp_' . $component_id;
+
+	// Use the meta type as a suffix for the field name.
+	if ( 'xprofile' === $component_id ) {
+		if ( ! in_array( $object_type, array( 'data', 'field', 'group' ), true ) ) {
+			return $registered_fields;
+		}
+
+		$field_name .= '_' . $object_type;
+	}
+
+	$args = bp_parse_args(
+		$args,
+		array(
+			'get_callback'    => null,
+			'update_callback' => null,
+			'schema'          => null,
+		),
+		'rest_register_field'
+	);
+
+	// Register the field.
+	register_rest_field( $field_name, $attribute, $args );
+
+	if ( isset( $GLOBALS['wp_rest_additional_fields'][ $field_name ] ) ) {
+		$registered_fields = $GLOBALS['wp_rest_additional_fields'][ $field_name ];
+	}
+
+	// Check it has been registered.
+	return isset( $registered_fields[ $attribute ] );
+}
diff --git src/bp-core/classes/class-bp-component.php src/bp-core/classes/class-bp-component.php
index 4802bf07f..7bed39f9e 100644
--- src/bp-core/classes/class-bp-component.php
+++ src/bp-core/classes/class-bp-component.php
@@ -461,6 +461,11 @@ class BP_Component {
 		// Generate rewrite rules.
 		add_action( 'bp_generate_rewrite_rules', array( $this, 'generate_rewrite_rules' ), 10 );
 
+		// Register BP REST Endpoints
+		if ( bp_rest_in_buddypress() && bp_rest_api_is_available() ) {
+			add_action( 'bp_rest_api_init', array( $this, 'rest_api_init' ), 10 );
+		}
+
 		/**
 		 * Fires at the end of the setup_actions method inside BP_Component.
 		 *
@@ -857,5 +862,22 @@ class BP_Component {
 		 */
 		do_action( 'bp_' . $this->id . '_generate_rewrite_rules' );
 	}
+
+	/**
+	 * Init the BP REST API.
+	 *
+	 * @since 5.0.0
+	 */
+	public function rest_api_init() {
+
+		/**
+		 * Fires in the rest_api_init method inside BP_Component.
+		 *
+		 * This is a dynamic hook that is based on the component string ID.
+		 *
+		 * @since 5.0.0
+		 */
+		do_action( 'bp_' . $this->id . '_rest_api_init' );
+	}
 }
 endif; // BP_Component.
diff --git src/bp-groups/classes/class-bp-groups-component.php src/bp-groups/classes/class-bp-groups-component.php
index 8953c1062..296c4833a 100644
--- src/bp-groups/classes/class-bp-groups-component.php
+++ src/bp-groups/classes/class-bp-groups-component.php
@@ -922,4 +922,28 @@ class BP_Groups_Component extends BP_Component {
 			'public' => false,
 		) );
 	}
+
+	/**
+	 * Init the BP REST API.
+	 *
+	 * @since 5.0.0
+	 */
+	public function rest_api_init() {
+		$controller = new BP_REST_Groups_Endpoint();
+		$controller->register_routes();
+
+		$controller = new BP_REST_Group_Membership_Endpoint();
+		$controller->register_routes();
+
+		$controller = new BP_REST_Group_Invites_Endpoint();
+		$controller->register_routes();
+
+		$controller = new BP_REST_Group_Membership_Request_Endpoint();
+		$controller->register_routes();
+
+		$controller = new BP_REST_Attachments_Group_Avatar_Endpoint();
+		$controller->register_routes();
+
+		parent::rest_api_init();
+	}
 }
diff --git src/bp-members/classes/class-bp-members-component.php src/bp-members/classes/class-bp-members-component.php
index 20c3eccee..4b1647976 100644
--- src/bp-members/classes/class-bp-members-component.php
+++ src/bp-members/classes/class-bp-members-component.php
@@ -456,4 +456,26 @@ class BP_Members_Component extends BP_Component {
 
 		parent::setup_cache_groups();
 	}
+
+	/**
+	 * Init the BP REST API.
+	 *
+	 * @since 5.0.0
+	 */
+	public function rest_api_init() {
+		/**
+		 * As the Members component is always loaded,
+		 * let's register the Components endpoint here.
+		 */
+		$controller = new BP_REST_Components_Endpoint();
+		$controller->register_routes();
+
+		$controller = new BP_REST_Members_Endpoint();
+		$controller->register_routes();
+
+		$controller = new BP_REST_Attachments_Member_Avatar_Endpoint();
+		$controller->register_routes();
+
+		parent::rest_api_init();
+	}
 }
diff --git src/bp-messages/classes/class-bp-messages-component.php src/bp-messages/classes/class-bp-messages-component.php
index b9ccc35ee..3062d5c5d 100644
--- src/bp-messages/classes/class-bp-messages-component.php
+++ src/bp-messages/classes/class-bp-messages-component.php
@@ -433,4 +433,16 @@ class BP_Messages_Component extends BP_Component {
 
 		parent::setup_cache_groups();
 	}
+
+	/**
+	 * Init the BP REST API.
+	 *
+	 * @since 5.0.0
+	 */
+	public function rest_api_init() {
+		$controller = new BP_REST_Messages_Endpoint();
+		$controller->register_routes();
+
+		parent::rest_api_init();
+	}
 }
diff --git src/bp-notifications/classes/class-bp-notifications-component.php src/bp-notifications/classes/class-bp-notifications-component.php
index 52716bfe8..2eaaba415 100644
--- src/bp-notifications/classes/class-bp-notifications-component.php
+++ src/bp-notifications/classes/class-bp-notifications-component.php
@@ -315,4 +315,16 @@ class BP_Notifications_Component extends BP_Component {
 
 		parent::setup_cache_groups();
 	}
+
+	/**
+	 * Init the BP REST API.
+	 *
+	 * @since 5.0.0
+	 */
+	public function rest_api_init() {
+		$controller = new BP_REST_Notifications_Endpoint();
+		$controller->register_routes();
+
+		parent::rest_api_init();
+	}
 }
diff --git src/bp-xprofile/classes/class-bp-xprofile-component.php src/bp-xprofile/classes/class-bp-xprofile-component.php
index 8b619afc9..3ade404aa 100644
--- src/bp-xprofile/classes/class-bp-xprofile-component.php
+++ src/bp-xprofile/classes/class-bp-xprofile-component.php
@@ -489,4 +489,22 @@ class BP_XProfile_Component extends BP_Component {
 
 		return $wp_admin_nav;
 	}
+
+	/**
+	 * Init the BP REST API.
+	 *
+	 * @since 5.0.0
+	 */
+	public function rest_api_init() {
+		$controller = new BP_REST_XProfile_Fields_Endpoint();
+		$controller->register_routes();
+
+		$controller = new BP_REST_XProfile_Field_Groups_Endpoint();
+		$controller->register_routes();
+
+		$controller = new BP_REST_XProfile_Data_Endpoint();
+		$controller->register_routes();
+
+		parent::rest_api_init();
+	}
 }
diff --git src/class-buddypress.php src/class-buddypress.php
index b5e6ef4a9..c3639b7d9 100644
--- src/class-buddypress.php
+++ src/class-buddypress.php
@@ -545,40 +545,49 @@ class BuddyPress {
 
 		// These classes don't have a name that matches their component.
 		$irregular_map = array(
-			'BP_Akismet' => 'activity',
-
-			'BP_Admin'                     => 'core',
-			'BP_Attachment_Avatar'         => 'core',
-			'BP_Attachment_Cover_Image'    => 'core',
-			'BP_Attachment'                => 'core',
-			'BP_Button'                    => 'core',
-			'BP_Component'                 => 'core',
-			'BP_Customizer_Control_Range'  => 'core',
-			'BP_Date_Query'                => 'core',
-			'BP_Email_Delivery'            => 'core',
-			'BP_Email_Address'             => 'core',
-			'BP_Email_Recipient'           => 'core',
-			'BP_Email_Sender'              => 'core',
-			'BP_Email_Participant'         => 'core',
-			'BP_Email'                     => 'core',
-			'BP_Embed'                     => 'core',
-			'BP_Media_Extractor'           => 'core',
-			'BP_Members_Suggestions'       => 'core',
-			'BP_PHPMailer'                 => 'core',
-			'BP_Recursive_Query'           => 'core',
-			'BP_Suggestions'               => 'core',
-			'BP_Theme_Compat'              => 'core',
-			'BP_User_Query'                => 'core',
-			'BP_Walker_Category_Checklist' => 'core',
-			'BP_Walker_Nav_Menu_Checklist' => 'core',
-			'BP_Walker_Nav_Menu'           => 'core',
-			'BP_Invitation_Manager'        => 'core',
-			'BP_Invitation'                => 'core',
+			'BP_Akismet'                => 'activity',
+			'BP_REST_Activity_Endpoint' => 'activity',
+
+			'BP_Admin'                                   => 'core',
+			'BP_Attachment_Avatar'                       => 'core',
+			'BP_Attachment_Cover_Image'                  => 'core',
+			'BP_Attachment'                              => 'core',
+			'BP_Button'                                  => 'core',
+			'BP_Component'                               => 'core',
+			'BP_Customizer_Control_Range'                => 'core',
+			'BP_Date_Query'                              => 'core',
+			'BP_Email_Delivery'                          => 'core',
+			'BP_Email_Address'                           => 'core',
+			'BP_Email_Recipient'                         => 'core',
+			'BP_Email_Sender'                            => 'core',
+			'BP_Email_Participant'                       => 'core',
+			'BP_Email'                                   => 'core',
+			'BP_Embed'                                   => 'core',
+			'BP_Media_Extractor'                         => 'core',
+			'BP_Members_Suggestions'                     => 'core',
+			'BP_PHPMailer'                               => 'core',
+			'BP_Recursive_Query'                         => 'core',
+			'BP_Suggestions'                             => 'core',
+			'BP_Theme_Compat'                            => 'core',
+			'BP_User_Query'                              => 'core',
+			'BP_Walker_Category_Checklist'               => 'core',
+			'BP_Walker_Nav_Menu_Checklist'               => 'core',
+			'BP_Walker_Nav_Menu'                         => 'core',
+			'BP_Invitation_Manager'                      => 'core',
+			'BP_Invitation'                              => 'core',
+			'BP_REST_Components_Endpoint'                => 'core',
+			'BP_REST_Attachments'                        => 'core',
+			'BP_REST_Attachments_Member_Avatar_Endpoint' => 'core',
+			'BP_REST_Attachments_Group_Avatar_Endpoint'  => 'core',
 
 			'BP_Core_Friends_Widget' => 'friends',
 
-			'BP_Group_Extension'    => 'groups',
-			'BP_Group_Member_Query' => 'groups',
+			'BP_Group_Extension'                        => 'groups',
+			'BP_Group_Member_Query'                     => 'groups',
+			'BP_REST_Groups_Endpoint'                   => 'groups',
+			'BP_REST_Group_Membership_Endpoint'         => 'groups',
+			'BP_REST_Group_Invites_Endpoint'            => 'groups',
+			'BP_REST_Group_Membership_Request_Endpoint' => 'groups',
 
 			'BP_Core_Members_Template'       => 'members',
 			'BP_Core_Members_Widget'         => 'members',
@@ -586,6 +595,15 @@ class BuddyPress {
 			'BP_Core_Whos_Online_Widget'     => 'members',
 			'BP_Registration_Theme_Compat'   => 'members',
 			'BP_Signup'                      => 'members',
+			'BP_REST_Members_Endpoint'       => 'members',
+
+			'BP_REST_Messages_Endpoint' => 'messages',
+
+			'BP_REST_Notifications_Endpoint' => 'notifications',
+
+			'BP_REST_XProfile_Fields_Endpoint'       => 'xprofile',
+			'BP_REST_XProfile_Field_Groups_Endpoint' => 'xprofile',
+			'BP_REST_XProfile_Data_Endpoint'         => 'xprofile',
 		);
 
 		$component = null;
@@ -606,7 +624,11 @@ class BuddyPress {
 		// Sanitize class name.
 		$class = strtolower( str_replace( '_', '-', $class ) );
 
-		$path = dirname( __FILE__ ) . "/bp-{$component}/classes/class-{$class}.php";
+		if ( 'bp-rest-attachments' === $class ) {
+			$path = dirname( __FILE__ ) . "/bp-{$component}/classes/trait-attachments.php";
+		} else {
+			$path = dirname( __FILE__ ) . "/bp-{$component}/classes/class-{$class}.php";
+		}
 
 		// Sanity check.
 		if ( ! file_exists( $path ) ) {
diff --git tests/phpunit/includes/testcase.php tests/phpunit/includes/testcase.php
index 1b5022ec4..1428a6e17 100644
--- tests/phpunit/includes/testcase.php
+++ tests/phpunit/includes/testcase.php
@@ -324,7 +324,7 @@ class BP_UnitTestCase extends WP_UnitTestCase {
 			$_SERVER['SERVER_NAME'] = self::$cached_SERVER_NAME;
 			self::$cached_SERVER_NAME = '';
 		} else {
-			unset( $_SERVER['SERVER_NAME'] );
+			$_SERVER['SERVER_NAME'] = WP_TESTS_DOMAIN;
 		}
 
 		// passthrough
