Index: src/wp-admin/includes/admin-filters.php
===================================================================
--- src/wp-admin/includes/admin-filters.php	(revision 39883)
+++ src/wp-admin/includes/admin-filters.php	(working copy)
@@ -55,10 +55,11 @@
 add_action( 'update_option_siteurl',       'update_home_siteurl', 10, 2 );
 add_action( 'update_option_page_on_front', 'update_home_siteurl', 10, 2 );
 
-add_filter( 'heartbeat_received', 'wp_check_locked_posts',  10,  3 );
-add_filter( 'heartbeat_received', 'wp_refresh_post_lock',   10,  3 );
-add_filter( 'wp_refresh_nonces', 'wp_refresh_post_nonces', 10,  3 );
-add_filter( 'heartbeat_received', 'heartbeat_autosave',     500, 2 );
+add_filter( 'heartbeat_received', 'wp_check_locked_posts',            10,  3 );
+add_filter( 'heartbeat_received', 'wp_refresh_post_lock',             10,  3 );
+add_filter( 'wp_refresh_nonces',  'wp_refresh_post_nonces',           10,  3 );
+add_filter( 'heartbeat_received', 'rest_refresh_nonce_on_heartbeat',  10,  2 );
+add_filter( 'heartbeat_received', 'heartbeat_autosave',               500, 2 );
 
 add_filter( 'heartbeat_settings', 'wp_heartbeat_set_suspension' );
 
Index: src/wp-includes/js/wp-api-nonce.js
===================================================================
--- src/wp-includes/js/wp-api-nonce.js	(nonexistent)
+++ src/wp-includes/js/wp-api-nonce.js	(working copy)
@@ -0,0 +1,10 @@
+jQuery( function ($) {
+	$( document ).on( 'heartbeat-send', function ( e, data ) {
+		data['wp-refresh-rest-nonce'] = wpApiSettings.nonce;
+	});
+	$( document ).on( 'heartbeat-tick', function ( e, data ) {
+		if ( 'wp-refresh-rest-nonce' in data ) {
+			wpApiSettings.nonce = data['wp-refresh-rest-nonce'];
+		}
+	});
+});
Index: src/wp-includes/rest-api.php
===================================================================
--- src/wp-includes/rest-api.php	(revision 39883)
+++ src/wp-includes/rest-api.php	(working copy)
@@ -721,6 +721,27 @@
 }
 
 /**
+ * Refresh the REST API nonce on heartbeat requests.
+ *
+ * @since 4.8
+ *
+ * @param array  $response  The Heartbeat response.
+ * @param array  $data      The $_POST data sent.
+ * @return array The Heartbeat response.
+ */
+function rest_refresh_nonce_on_heartbeat( $response, $data ) {
+	if ( array_key_exists( 'wp-refresh-rest-nonce', $data ) ) {
+		// Are we in the second tick?
+		if ( wp_verify_nonce( $data['wp-refresh-rest-nonce'] ) === 2 ) {
+			// Update nonce.
+			$response['wp-refresh-rest-nonce'] = wp_create_nonce( 'wp_rest' );
+		}
+	}
+
+	return $response;
+}
+
+/**
  * Collects cookie authentication status.
  *
  * Collects errors from wp_validate_auth_cookie for use by rest_cookie_check_errors.
Index: src/wp-includes/script-loader.php
===================================================================
--- src/wp-includes/script-loader.php	(revision 39883)
+++ src/wp-includes/script-loader.php	(working copy)
@@ -510,6 +510,7 @@
 		'nonce'         => ( wp_installing() && ! is_multisite() ) ? '' : wp_create_nonce( 'wp_rest' ),
 		'versionString' => 'wp/v2/',
 	) );
+	$scripts->add( 'wp-api-nonce', "/wp-includes/js/wp-api-nonce$suffix.js", array( 'jquery', 'wp-api', 'heartbeat' ), false, 1 );
 
 	if ( is_admin() ) {
 		$scripts->add( 'admin-tags', "/wp-admin/js/tags$suffix.js", array( 'jquery', 'wp-ajax-response' ), false, 1 );
