diff --git a/src/wp-includes/rest-api/class-wp-rest-response.php b/src/wp-includes/rest-api/class-wp-rest-response.php
index db80029..3bbbd8c 100644
--- a/src/wp-includes/rest-api/class-wp-rest-response.php
+++ b/src/wp-includes/rest-api/class-wp-rest-response.php
@@ -256,4 +256,21 @@ class WP_REST_Response extends WP_HTTP_Response {
 
 		return $error;
 	}
+
+	/**
+	 * Get the CURIEs (compact URIs) used for relations.
+	 *
+	 * @return array
+	 */
+	public function get_curies() {
+		$curies = array(
+			array(
+				'name' => 'wp',
+				'href' => 'https://api.w.org/{rel}',
+				'templated' => true,
+			),
+		);
+
+		return array_merge( $curies, apply_filters( 'rest_response_link_curies', array() ) );
+	}
 }
diff --git a/src/wp-includes/rest-api/class-wp-rest-server.php b/src/wp-includes/rest-api/class-wp-rest-server.php
index dad4070..98f174e 100644
--- a/src/wp-includes/rest-api/class-wp-rest-server.php
+++ b/src/wp-includes/rest-api/class-wp-rest-server.php
@@ -460,7 +460,28 @@ class WP_REST_Server {
 
 		// Convert links to part of the data.
 		$data = array();
+		$curies = $response->get_curies();
+		$used_curies = array();
+
 		foreach ( $links as $rel => $items ) {
+
+			// Convert $rel URIs to their compact versions if they exist.
+			foreach ( $curies as $curie ) {
+				$href_prefix = substr( $curie['href'], 0, strpos( $curie['href'], '{rel}' ) );
+				if ( strpos( $rel, $href_prefix ) !== 0 ) {
+					continue;
+				}
+				$used_curies[ $curie['name'] ] = $curie;
+
+				// Relation now changes from '$uri' to '$curie:$relation'
+				$rel_regex = str_replace( '\{rel\}', '([\w]+)', preg_quote( $curie['href'], '!' ) );
+				preg_match( '!' . $rel_regex . '!', $rel, $matches );
+				if ( $matches ) {
+					$rel = $curie['name'] . ':' . $matches[1];
+				}
+				break;
+			}
+
 			$data[ $rel ] = array();
 
 			foreach ( $items as $item ) {
@@ -470,6 +491,11 @@ class WP_REST_Server {
 			}
 		}
 
+		// Push the curies onto the start of the links array.
+		if ( $used_curies ) {
+			$data = array_merge( array( 'curies' => array_values( $used_curies ) ), $data );
+		}
+
 		return $data;
 	}
 
diff --git a/tests/phpunit/tests/rest-api/rest-server.php b/tests/phpunit/tests/rest-api/rest-server.php
index 33e3f24..4763edf 100644
--- a/tests/phpunit/tests/rest-api/rest-server.php
+++ b/tests/phpunit/tests/rest-api/rest-server.php
@@ -393,6 +393,45 @@ class Tests_REST_Server extends WP_Test_REST_TestCase {
 		$this->assertEquals( 'embed', $alternate[1]['parameters']['context'] );
 	}
 
+	public function test_link_curies() {
+		$response = new WP_REST_Response();
+		$response->add_link( 'https://api.w.org/term', 'http://example.com/' );
+
+		$data = $this->server->response_to_data( $response, false );
+		$links = $data['_links'];
+
+		$this->assertArrayHasKey( 'wp:term', $links );
+		$this->assertArrayHasKey( 'curies', $links );
+	}
+
+	public function test_custom_curie_link() {
+		$response = new WP_REST_Response();
+		$response->add_link( 'http://mysite.com/contact.html', 'http://example.com/' );
+
+		add_filter( 'rest_response_link_curies', array( $this, 'add_custom_curie' ) );
+
+		$data = $this->server->response_to_data( $response, false );
+		$links = $data['_links'];
+
+		$this->assertArrayHasKey( 'my_site:contact', $links );
+		$this->assertArrayHasKey( 'curies', $links );
+	}
+
+	/**
+	 * Helper callback to add a new custom curie via a filter.
+	 *
+	 * @param array $curies
+	 * @return array
+	 */
+	public function add_custom_curie( $curies ) {
+		$curies[] = array(
+			'name'      => 'my_site',
+			'href'      => 'http://mysite.com/{rel}.html',
+			'templated' => true,
+		);
+		return $curies;
+	}
+
 	/**
 	 * @depends test_link_embedding
 	 */
