diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 15c452e..17cdfdd 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -45,7 +45,7 @@ The WordPress REST API response doesn't fully adhere to the JSON schema spec, so
   - Start by copying an existing file such as `post.php` which is for `/wp/v2/posts`
   - The command should perform one or more REST API requests to the endpoint and pass the responses to the `save_rest_array()` function which saves them as JSON during the tests
 * Run `composer run test` to validate and test the schemas.
-* Run `npm run build-wp-types` and check the output of `packages/wp-types/index.ts`.
+* Check the output of `packages/wp-types/index.ts`.
 * Add documentation for the schema in both `readme.md` and `packages/wp-types/readme.md`.
 
 ## Creating a PHP object schema
@@ -69,7 +69,7 @@ The schema for a PHP object is created using the docblocks from its class proper
   - Start by copying an existing file such as `error.php`
   - The file should pass an array of one or more objects of this type to the `save_object_array()` function which saves it as JSON during the tests
 * Run `composer run test` to validate and test the schemas.
-* Run `npm run build-wp-types` and check the output of `packages/wp-types/index.ts`.
+* Check the output of `packages/wp-types/index.ts`.
 * Add documentation for the schema in both `readme.md` and `packages/wp-types/readme.md`.
 
 ## Updating schemas for a new WordPress release
diff --git a/composer.json b/composer.json
index 0ebe16a..3985824 100644
--- a/composer.json
+++ b/composer.json
@@ -25,6 +25,7 @@
 	"require-dev": {
 		"ext-sqlite3": "*",
 		"ext-pdo_sqlite": "*",
+		"ergebnis/json-printer": "^3.5",
 		"johnbillion/args": "1.7.0",
 		"roots/wordpress-core-installer": "^1.0.0",
 		"roots/wordpress-full": "6.6-RC3",
diff --git a/packages/wp-types/index.ts b/packages/wp-types/index.ts
index 74c89ec..0adfa8a 100644
--- a/packages/wp-types/index.ts
+++ b/packages/wp-types/index.ts
@@ -40,6 +40,14 @@ export type WP_REST_API_Comments = WP_REST_API_Comment[];
  * A collection of font collection objects in a REST API context.
  */
 export type WP_REST_API_Font_Collections = WP_REST_API_Font_Collection[];
+/**
+ * A collection of font family objects in a REST API context.
+ */
+export type WP_REST_API_Font_Families = WP_REST_API_Font_Family[];
+/**
+ * A collection of font face objects in a REST API context.
+ */
+export type WP_REST_API_Font_Faces = WP_REST_API_Font_Face[];
 /**
  * A collection of post objects in a REST API context.
  */
@@ -144,6 +152,10 @@ export interface WP {
 		Comments: WP_REST_API_Comments;
 		Font_Collection: WP_REST_API_Font_Collection;
 		Font_Collections: WP_REST_API_Font_Collections;
+		Font_Family: WP_REST_API_Font_Family;
+		Font_Families: WP_REST_API_Font_Families;
+		Font_Face: WP_REST_API_Font_Face;
+		Font_Faces: WP_REST_API_Font_Faces;
 		Post: WP_REST_API_Post;
 		Posts: WP_REST_API_Posts;
 		Page: WP_REST_API_Page;
@@ -1912,74 +1924,7 @@ export interface WP_REST_API_Font_Collection {
 	 * The font families for the font collection.
 	 */
 	font_families: {
-		font_family_settings: {
-			name: string;
-			fontFamily: string;
-			slug: string;
-			fontFace?: {
-				/**
-				 * URL to a preview image of the font.
-				 */
-				preview?: string;
-				/**
-				 * CSS font-family value.
-				 */
-				fontFamily: string;
-				/**
-				 * CSS font-style value.
-				 */
-				fontStyle?: string;
-				/**
-				 * List of available font weights, separated by a space.
-				 */
-				fontWeight?: string | number;
-				/**
-				 * CSS font-display value.
-				 */
-				fontDisplay?: "auto" | "block" | "fallback" | "swap" | "optional";
-				/**
-				 * Paths or URLs to the font files.
-				 */
-				src: string | string[];
-				/**
-				 * CSS font-stretch value.
-				 */
-				fontStretch?: string;
-				/**
-				 * CSS ascent-override value.
-				 */
-				ascentOverride?: string;
-				/**
-				 * CSS descent-override value.
-				 */
-				descentOverride?: string;
-				/**
-				 * CSS font-variant value.
-				 */
-				fontVariant?: string;
-				/**
-				 * CSS font-feature-settings value.
-				 */
-				fontFeatureSettings?: string;
-				/**
-				 * CSS font-variation-settings value.
-				 */
-				fontVariationSettings?: string;
-				/**
-				 * CSS line-gap-override value.
-				 */
-				lineGapOverride?: string;
-				/**
-				 * CSS size-adjust value.
-				 */
-				sizeAdjust?: string;
-				/**
-				 * CSS unicode-range value.
-				 */
-				unicodeRange?: string;
-			}[];
-			preview?: string;
-		};
+		font_family_settings: WP_Font_Family_Settings;
 		categories?: string[];
 	}[];
 	/**
@@ -1992,6 +1937,160 @@ export interface WP_REST_API_Font_Collection {
 	_links: WP_REST_API_Object_Links;
 	[k: string]: unknown;
 }
+/**
+ * Font family settings.
+ */
+export interface WP_Font_Family_Settings {
+	name: string;
+	fontFamily: string;
+	slug: string;
+	fontFace?: WP_Font_Face[];
+	preview?: string;
+}
+/**
+ * A font face.
+ */
+export interface WP_Font_Face {
+	/**
+	 * URL to a preview image of the font.
+	 */
+	preview?: string;
+	/**
+	 * CSS font-family value.
+	 */
+	fontFamily: string;
+	/**
+	 * CSS font-style value.
+	 */
+	fontStyle?: string;
+	/**
+	 * List of available font weights, separated by a space.
+	 */
+	fontWeight?: string | number;
+	/**
+	 * CSS font-display value.
+	 */
+	fontDisplay?: "auto" | "block" | "fallback" | "swap" | "optional";
+	/**
+	 * Paths or URLs to the font files.
+	 */
+	src: string | string[];
+	/**
+	 * CSS font-stretch value.
+	 */
+	fontStretch?: string;
+	/**
+	 * CSS ascent-override value.
+	 */
+	ascentOverride?: string;
+	/**
+	 * CSS descent-override value.
+	 */
+	descentOverride?: string;
+	/**
+	 * CSS font-variant value.
+	 */
+	fontVariant?: string;
+	/**
+	 * CSS font-feature-settings value.
+	 */
+	fontFeatureSettings?: string;
+	/**
+	 * CSS font-variation-settings value.
+	 */
+	fontVariationSettings?: string;
+	/**
+	 * CSS line-gap-override value.
+	 */
+	lineGapOverride?: string;
+	/**
+	 * CSS size-adjust value.
+	 */
+	sizeAdjust?: string;
+	/**
+	 * CSS unicode-range value.
+	 */
+	unicodeRange?: string;
+}
+/**
+ * A font family object in a REST API context.
+ */
+export interface WP_REST_API_Font_Family {
+	/**
+	 * Unique identifier for the font family.
+	 */
+	id: number;
+	/**
+	 * Version of the theme.json schema used for the typography settings.
+	 */
+	theme_json_version: number;
+	/**
+	 * The IDs of the child font faces in the font family.
+	 */
+	font_faces: number[];
+	font_family_settings: WP_Font_Family_Settings;
+	_links: WP_REST_API_Object_Links;
+	/**
+	 * The embedded representation of relations. Only present when the '_embed' query parameter is set.
+	 */
+	_embedded?: {
+		/**
+		 * The associated font faces.
+		 */
+		font_faces?: unknown[];
+		[k: string]: unknown;
+	};
+	[k: string]: unknown;
+}
+/**
+ * A font face object in a REST API context.
+ */
+export interface WP_REST_API_Font_Face {
+	/**
+	 * Unique identifier for the font face.
+	 */
+	id: number;
+	/**
+	 * Version of the theme.json schema used for the typography settings.
+	 */
+	theme_json_version: number;
+	/**
+	 * The ID for the parent font family of the font face.
+	 */
+	parent: number;
+	/**
+	 * font-face declaration in theme.json format.
+	 */
+	font_face_settings: {
+		/**
+		 * Unique identifier for the font family.
+		 */
+		id?: number;
+		/**
+		 * Version of the theme.json schema used for the typography settings.
+		 */
+		theme_json_version?: number;
+		/**
+		 * The IDs of the child font faces in the font family.
+		 */
+		font_faces?: number[];
+		font_family_settings?: WP_Font_Family_Settings;
+		_links?: WP_REST_API_Object_Links;
+		/**
+		 * The embedded representation of relations. Only present when the '_embed' query parameter is set.
+		 */
+		_embedded?: {
+			/**
+			 * The associated font faces.
+			 */
+			font_faces?: unknown[];
+			[k: string]: unknown;
+		};
+		[k: string]: unknown;
+	};
+	_links: WP_REST_API_Object_Links;
+	[k: string]: unknown;
+}
 /**
  * A post object in a REST API context.
  */
diff --git a/packages/wp-types/readme.md b/packages/wp-types/readme.md
index 89e6ce8..7321812 100644
--- a/packages/wp-types/readme.md
+++ b/packages/wp-types/readme.md
@@ -52,12 +52,12 @@ Route                                                   | Schema
 /wp/v2/categories/{id}                                  | `WP_REST_API_Category`
 /wp/v2/comments                                         | `WP_REST_API_Comments`
 /wp/v2/comments/{id}                                    | `WP_REST_API_Comment`
-/wp/v2/wp/v2/font-collections                           | `WP_REST_API_Font_Collections`
-/wp/v2/wp/v2/font-collections/{slug}                    | `WP_REST_API_Font_Collection`
-/wp/v2/wp/v2/font-families                              | Todo
-/wp/v2/wp/v2/font-families/{id}/                        | Todo
-/wp/v2/wp/v2/font-families/{id}/font-faces              | Todo
-/wp/v2/wp/v2/font-families/{id}/font-faces/{id}         | Todo
+/wp/v2/font-collections                                 | `WP_REST_API_Font_Collections`
+/wp/v2/font-collections/{slug}                          | `WP_REST_API_Font_Collection`
+/wp/v2/font-families                                    | `WP_REST_API_Font_Families`
+/wp/v2/font-families/{id}/                              | `WP_REST_API_Font_Family`
+/wp/v2/font-families/{parent}/font-faces                | `WP_REST_API_Font_Faces`
+/wp/v2/font-families/{parent}/font-faces/{id}           | `WP_REST_API_Font_Face`
 /wp/v2/global-styles/{id}                               | Todo
 /wp/v2/global-styles/{parent}/revisions                 | Todo
 /wp/v2/global-styles/{parent}/revisions/{id}            | Todo
diff --git a/readme.md b/readme.md
index 7a7eb2d..2c8217a 100644
--- a/readme.md
+++ b/readme.md
@@ -56,12 +56,12 @@ Route                                                   | Schema
 /wp/v2/categories/{id}                                  | `WP_REST_API_Category`
 /wp/v2/comments                                         | `WP_REST_API_Comments`
 /wp/v2/comments/{id}                                    | `WP_REST_API_Comment`
-/wp/v2/wp/v2/font-collections                           | `WP_REST_API_Font_Collections`
-/wp/v2/wp/v2/font-collections/{slug}                    | `WP_REST_API_Font_Collection`
-/wp/v2/wp/v2/font-families                              | Todo
-/wp/v2/wp/v2/font-families/{id}/                        | Todo
-/wp/v2/wp/v2/font-families/{id}/font-faces              | Todo
-/wp/v2/wp/v2/font-families/{id}/font-faces/{id}         | Todo
+/wp/v2/font-collections                                 | `WP_REST_API_Font_Collections`
+/wp/v2/font-collections/{slug}                          | `WP_REST_API_Font_Collection`
+/wp/v2/font-families                                    | `WP_REST_API_Font_Families`
+/wp/v2/font-families/{id}/                              | `WP_REST_API_Font_Family`
+/wp/v2/font-families/{parent}/font-faces                | `WP_REST_API_Font_Faces`
+/wp/v2/font-families/{parent}/font-faces/{id}           | `WP_REST_API_Font_Face`
 /wp/v2/global-styles/{id}                               | Todo
 /wp/v2/global-styles/{parent}/revisions                 | Todo
 /wp/v2/global-styles/{parent}/revisions/{id}            | Todo
diff --git a/schema.json b/schema.json
index e8b19f7..a07a8cb 100644
--- a/schema.json
+++ b/schema.json
@@ -86,6 +86,18 @@
 				"Font_Collections": {
 					"$ref": "schemas/rest-api/collections/font-collections.json"
 				},
+				"Font_Family": {
+					"$ref": "schemas/rest-api/font-family.json"
+				},
+				"Font_Families": {
+					"$ref": "schemas/rest-api/collections/font-families.json"
+				},
+				"Font_Face": {
+					"$ref": "schemas/rest-api/font-face.json"
+				},
+				"Font_Faces": {
+					"$ref": "schemas/rest-api/collections/font-faces.json"
+				},
 				"Post": {
 					"$ref": "schemas/rest-api/post.json"
 				},
@@ -209,6 +221,10 @@
 				"Comments",
 				"Font_Collection",
 				"Font_Collections",
+				"Font_Family",
+				"Font_Families",
+				"Font_Face",
+				"Font_Faces",
 				"Post",
 				"Posts",
 				"Page",
diff --git a/schemas/rest-api/collections/font-faces.json b/schemas/rest-api/collections/font-faces.json
new file mode 100644
index 0000000..caef5e7
--- /dev/null
+++ b/schemas/rest-api/collections/font-faces.json
@@ -0,0 +1,10 @@
+{
+	"$schema": "http://json-schema.org/draft-07/hyper-schema#",
+	"$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/collections/font-faces.json",
+	"title": "WP_REST_API_Font_Faces",
+	"description": "A collection of font face objects in a REST API context.",
+	"type": "array",
+	"items": {
+		"$ref": "../font-face.json"
+	}
+}
diff --git a/schemas/rest-api/collections/font-families.json b/schemas/rest-api/collections/font-families.json
new file mode 100644
index 0000000..7a1a895
--- /dev/null
+++ b/schemas/rest-api/collections/font-families.json
@@ -0,0 +1,19 @@
+{
+	"$schema": "http://json-schema.org/draft-07/hyper-schema#",
+	"$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/collections/font-families.json",
+	"title": "WP_REST_API_Font_Families",
+	"description": "A collection of font family objects in a REST API context.",
+	"type": "array",
+	"items": {
+		"$ref": "../font-family.json"
+	},
+	"links": [
+		{
+			"rel": "self",
+			"href": "/wp/v2/font-families",
+			"targetSchema": {
+				"$ref": "#"
+			}
+		}
+	]
+}
diff --git a/schemas/rest-api/font-collection.json b/schemas/rest-api/font-collection.json
index 9f97fc7..37aa8b5 100644
--- a/schemas/rest-api/font-collection.json
+++ b/schemas/rest-api/font-collection.json
@@ -37,126 +37,11 @@
 				],
 				"properties": {
 					"font_family_settings": {
-						"type": "object",
-						"required": [
-							"name",
-							"fontFamily",
-							"slug"
-						],
-						"properties": {
-							"name": {
-								"type": "string"
-							},
-							"fontFamily": {
-								"type": "string"
-							},
-							"slug": {
-								"type": "string"
-							},
-							"fontFace": {
-								"type": "array",
-								"items": {
-									"type": "object",
-									"required": [
-										"src",
-										"fontFamily"
-									],
-									"properties": {
-										"preview": {
-											"description": "URL to a preview image of the font.",
-											"type": "string",
-											"format": "uri"
-										},
-										"fontFamily": {
-											"description": "CSS font-family value.",
-											"type": "string"
-										},
-										"fontStyle": {
-											"description": "CSS font-style value.",
-											"type": "string"
-										},
-										"fontWeight": {
-											"description": "List of available font weights, separated by a space.",
-											"oneOf": [
-												{
-													"type": "string"
-												},
-												{
-													"type": "integer"
-												}
-											]
-										},
-										"fontDisplay": {
-											"description": "CSS font-display value.",
-											"type": "string",
-											"enum": [
-												"auto",
-												"block",
-												"fallback",
-												"swap",
-												"optional"
-											]
-										},
-										"src": {
-											"description": "Paths or URLs to the font files.",
-											"oneOf": [
-												{
-													"type": "string"
-												},
-												{
-													"type": "array",
-													"items": {
-														"type": "string"
-													}
-												}
-											]
-										},
-										"fontStretch": {
-											"description": "CSS font-stretch value.",
-											"type": "string"
-										},
-										"ascentOverride": {
-											"description": "CSS ascent-override value.",
-											"type": "string"
-										},
-										"descentOverride": {
-											"description": "CSS descent-override value.",
-											"type": "string"
-										},
-										"fontVariant": {
-											"description": "CSS font-variant value.",
-											"type": "string"
-										},
-										"fontFeatureSettings": {
-											"description": "CSS font-feature-settings value.",
-											"type": "string"
-										},
-										"fontVariationSettings": {
-											"description": "CSS font-variation-settings value.",
-											"type": "string"
-										},
-										"lineGapOverride": {
-											"description": "CSS line-gap-override value.",
-											"type": "string"
-										},
-										"sizeAdjust": {
-											"description": "CSS size-adjust value.",
-											"type": "string"
-										},
-										"unicodeRange": {
-											"description": "CSS unicode-range value.",
-											"type": "string"
-										}
-									},
-									"additionalProperties": false
-								}
-							},
-							"preview": {
-								"type": "string",
-								"format": "uri"
+						"oneOf": [
+							{
+								"$ref": "properties/font-family-settings.json"
 							}
-						},
-						"additionalProperties": false
+						]
 					},
 					"categories": {
 						"type": "array",
diff --git a/schemas/rest-api/font-face.json b/schemas/rest-api/font-face.json
new file mode 100644
index 0000000..a118a60
--- /dev/null
+++ b/schemas/rest-api/font-face.json
@@ -0,0 +1,125 @@
+{
+	"$schema": "http://json-schema.org/draft-07/hyper-schema#",
+	"$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/font-face.json",
+	"title": "WP_REST_API_Font_Face",
+	"description": "A font face object in a REST API context.",
+	"$comment": "See also https://schemas.wp.org/trunk/font-face.json",
+	"type": "object",
+	"required": [
+		"id",
+		"theme_json_version",
+		"parent",
+		"font_face_settings",
+		"_links"
+	],
+	"properties": {
+		"id": {
+			"readOnly": true,
+			"description": "Unique identifier for the font face.",
+			"type": "integer"
+		},
+		"theme_json_version": {
+			"description": "Version of the theme.json schema used for the typography settings.",
+			"type": "integer"
+		},
+		"parent": {
+			"description": "The ID for the parent font family of the font face.",
+			"type": "integer"
+		},
+		"font_face_settings": {
+			"description": "font-face declaration in theme.json format.",
+			"type": "object",
+			"properties": {
+				"id": {
+					"readOnly": true,
+					"description": "Unique identifier for the font family.",
+					"type": "integer"
+				},
+				"theme_json_version": {
+					"description": "Version of the theme.json schema used for the typography settings.",
+					"type": "integer"
+				},
+				"font_faces": {
+					"description": "The IDs of the child font faces in the font family.",
+					"type": "array",
+					"items": {
+						"type": "integer"
+					}
+				},
+				"font_family_settings": {
+					"oneOf": [
+						{
+							"$ref": "properties/font-family-settings.json"
+						}
+					]
+				},
+				"_links": {
+					"$ref": "properties/object-links.json"
+				},
+				"_embedded": {
+					"description": "The embedded representation of relations. Only present when the '_embed' query parameter is set.",
+					"type": "object",
+					"properties": {
+						"font_faces": {
+							"description": "The associated font faces.",
+							"type": "array"
+						}
+					}
+				}
+			}
+		},
+		"_links": {
+			"$ref": "properties/object-links.json"
+		}
+	},
+	"links": [
+		{
+			"rel": "self",
+			"href": "/wp/v2/font-families/{parent}/font-faces/{id}",
+			"hrefSchema": {
+				"properties": {
+					"parent": {
+						"$ref": "#/properties/parent"
+					},
+					"id": {
+						"$ref": "#/properties/id"
+					}
+				}
+			},
+			"targetSchema": {
+				"$ref": "#"
+			}
+		},
+		{
+			"rel": "collection",
+			"href": "/wp/v2/font-families/{parent}/font-faces",
+			"hrefSchema": {
+				"properties": {
+					"parent": {
+						"$ref": "#/properties/parent"
+					}
+				}
+			},
+			"targetSchema": {
+				"type": "array",
+				"items": {
+					"$ref": "#"
+				}
+			}
+		},
+		{
+			"rel": "parent",
+			"href": "/wp/v2/font-families/{parent}",
+			"hrefSchema": {
+				"properties": {
+					"parent": {
+						"$ref": "#/properties/parent"
+					}
+				}
+			},
+			"targetSchema": {
+				"$ref": "font-family.json"
+			}
+		}
+	]
+}
diff --git a/schemas/rest-api/font-family.json b/schemas/rest-api/font-family.json
new file mode 100644
index 0000000..f8c5414
--- /dev/null
+++ b/schemas/rest-api/font-family.json
@@ -0,0 +1,79 @@
+{
+	"$schema": "http://json-schema.org/draft-07/hyper-schema#",
+	"$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/font-family.json",
+	"title": "WP_REST_API_Font_Family",
+	"description": "A font family object in a REST API context.",
+	"$comment": "See also https://schemas.wp.org/trunk/font-family.json",
+	"type": "object",
+	"required": [
+		"id",
+		"theme_json_version",
+		"font_faces",
+		"font_family_settings",
+		"_links"
+	],
+	"properties": {
+		"id": {
+			"readOnly": true,
+			"description": "Unique identifier for the font family.",
+			"type": "integer"
+		},
+		"theme_json_version": {
+			"description": "Version of the theme.json schema used for the typography settings.",
+			"type": "integer"
+		},
+		"font_faces": {
+			"description": "The IDs of the child font faces in the font family.",
+			"type": "array",
+			"items": {
+				"type": "integer"
+			}
+		},
+		"font_family_settings": {
+			"oneOf": [
+				{
+					"$ref": "properties/font-family-settings.json"
+				}
+			]
+		},
+		"_links": {
+			"$ref": "properties/object-links.json"
+		},
+		"_embedded": {
+			"description": "The embedded representation of relations. Only present when the '_embed' query parameter is set.",
+			"type": "object",
+			"properties": {
+				"font_faces": {
+					"description": "The associated font faces.",
+					"type": "array"
+				}
+			}
+		}
+	},
+	"links": [
+		{
+			"rel": "self",
+			"href": "/wp/v2/font-families/{id}",
+			"hrefSchema": {
+				"properties": {
+					"id": {
+						"$ref": "#/properties/id"
+					}
+				}
+			},
+			"targetSchema": {
+				"$ref": "#"
+			}
+		},
+		{
+			"rel": "collection",
+			"href": "/wp/v2/font-families",
+			"targetSchema": {
+				"type": "array",
+				"items": {
+					"$ref": "#"
+				}
+			}
+		}
+	]
+}
diff --git a/schemas/rest-api/properties/font-face.json b/schemas/rest-api/properties/font-face.json
new file mode 100644
index 0000000..2587799
--- /dev/null
+++ b/schemas/rest-api/properties/font-face.json
@@ -0,0 +1,99 @@
+{
+	"$schema": "http://json-schema.org/draft-07/hyper-schema#",
+	"$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/properties/font-face.json",
+	"title": "WP_Font_Face",
+	"description": "A font face.",
+	"type": "object",
+	"required": [
+		"src",
+		"fontFamily"
+	],
+	"properties": {
+		"preview": {
+			"description": "URL to a preview image of the font.",
+			"type": "string",
+			"format": "uri"
+		},
+		"fontFamily": {
+			"description": "CSS font-family value.",
+			"type": "string"
+		},
+		"fontStyle": {
+			"description": "CSS font-style value.",
+			"type": "string"
+		},
+		"fontWeight": {
+			"description": "List of available font weights, separated by a space.",
+			"oneOf": [
+				{
+					"type": "string"
+				},
+				{
+					"type": "integer"
+				}
+			]
+		},
+		"fontDisplay": {
+			"description": "CSS font-display value.",
+			"type": "string",
+			"enum": [
+				"auto",
+				"block",
+				"fallback",
+				"swap",
+				"optional"
+			]
+		},
+		"src": {
+			"description": "Paths or URLs to the font files.",
+			"oneOf": [
+				{
+					"type": "string"
+				},
+				{
+					"type": "array",
+					"items": {
+						"type": "string"
+					}
+				}
+			]
+		},
+		"fontStretch": {
+			"description": "CSS font-stretch value.",
+			"type": "string"
+		},
+		"ascentOverride": {
+			"description": "CSS ascent-override value.",
+			"type": "string"
+		},
+		"descentOverride": {
+			"description": "CSS descent-override value.",
+			"type": "string"
+		},
+		"fontVariant": {
+			"description": "CSS font-variant value.",
+			"type": "string"
+		},
+		"fontFeatureSettings": {
+			"description": "CSS font-feature-settings value.",
+			"type": "string"
+		},
+		"fontVariationSettings": {
+			"description": "CSS font-variation-settings value.",
+			"type": "string"
+		},
+		"lineGapOverride": {
+			"description": "CSS line-gap-override value.",
+			"type": "string"
+		},
+		"sizeAdjust": {
+			"description": "CSS size-adjust value.",
+			"type": "string"
+		},
+		"unicodeRange": {
+			"description": "CSS unicode-range value.",
+			"type": "string"
+		}
+	},
+	"additionalProperties": false
+}
diff --git a/schemas/rest-api/properties/font-family-settings.json b/schemas/rest-api/properties/font-family-settings.json
new file mode 100644
index 0000000..d66ee7d
--- /dev/null
+++ b/schemas/rest-api/properties/font-family-settings.json
@@ -0,0 +1,38 @@
+{
+	"$schema": "http://json-schema.org/draft-07/hyper-schema#",
+	"$id": "https://raw.githubusercontent.com/johnbillion/wp-json-schemas/trunk/schemas/rest-api/properties/font-family-settings.json",
+	"title": "WP_Font_Family_Settings",
+	"description": "Font family settings.",
+	"type": "object",
+	"required": [
+		"name",
+		"fontFamily",
+		"slug"
+	],
+	"properties": {
+		"name": {
+			"type": "string"
+		},
+		"fontFamily": {
+			"type": "string"
+		},
+		"slug": {
+			"type": "string"
+		},
+		"fontFace": {
+			"type": "array",
+			"items": {
+				"oneOf": [
+					{
+						"$ref": "./font-face.json"
+					}
+				]
+			}
+		},
+		"preview": {
+			"type": "string",
+			"format": "uri"
+		}
+	},
+	"additionalProperties": false
+}
diff --git a/tests/external-schemas/font-collection.json b/tests/external-schemas/font-collection.json
index e52455b..05f4657 100644
--- a/tests/external-schemas/font-collection.json
+++ b/tests/external-schemas/font-collection.json
@@ -37,7 +37,13 @@
 					"description": "CSS font-display value.",
 					"type": "string",
 					"default": "fallback",
-					"enum": [ "auto", "block", "fallback", "swap", "optional" ]
+					"enum": [
+						"auto",
+						"block",
+						"fallback",
+						"swap",
+						"optional"
+					]
 				},
 				"src": {
 					"description": "Paths or URLs to the font files.",
@@ -91,7 +97,10 @@
 					"type": "string"
 				}
 			},
-			"required": [ "fontFamily", "src" ],
+			"required": [
+				"fontFamily",
+				"src"
+			],
 			"additionalProperties": false
 		}
 	},
@@ -138,7 +147,11 @@
 								}
 							}
 						},
-						"required": [ "name", "fontFamily", "slug" ],
+						"required": [
+							"name",
+							"fontFamily",
+							"slug"
+						],
 						"additionalProperties": false
 					},
 					"categories": {
@@ -149,11 +162,15 @@
 						}
 					}
 				},
-				"required": [ "font_family_settings" ],
+				"required": [
+					"font_family_settings"
+				],
 				"additionalProperties": false
 			}
 		}
 	},
 	"additionalProperties": false,
-	"required": [ "font_families" ]
-}
+	"required": [
+		"font_families"
+	]
+}
\ No newline at end of file
diff --git a/tests/external-schemas/font-face.json b/tests/external-schemas/font-face.json
new file mode 100644
index 0000000..757e0e4
--- /dev/null
+++ b/tests/external-schemas/font-face.json
@@ -0,0 +1,95 @@
+{
+	"type": "object",
+	"properties": {
+		"fontFamily": {
+			"description": "CSS font-family value.",
+			"type": "string",
+			"default": ""
+		},
+		"fontStyle": {
+			"description": "CSS font-style value.",
+			"type": "string",
+			"default": "normal"
+		},
+		"fontWeight": {
+			"description": "List of available font weights, separated by a space.",
+			"default": "400",
+			"oneOf": [
+				{
+					"type": "string"
+				},
+				{
+					"type": "integer"
+				}
+			]
+		},
+		"fontDisplay": {
+			"description": "CSS font-display value.",
+			"type": "string",
+			"default": "fallback",
+			"enum": [
+				"auto",
+				"block",
+				"fallback",
+				"swap",
+				"optional"
+			]
+		},
+		"src": {
+			"description": "Paths or URLs to the font files.",
+			"oneOf": [
+				{
+					"type": "string"
+				},
+				{
+					"type": "array",
+					"items": {
+						"type": "string"
+					}
+				}
+			],
+			"default": []
+		},
+		"fontStretch": {
+			"description": "CSS font-stretch value.",
+			"type": "string"
+		},
+		"ascentOverride": {
+			"description": "CSS ascent-override value.",
+			"type": "string"
+		},
+		"descentOverride": {
+			"description": "CSS descent-override value.",
+			"type": "string"
+		},
+		"fontVariant": {
+			"description": "CSS font-variant value.",
+			"type": "string"
+		},
+		"fontFeatureSettings": {
+			"description": "CSS font-feature-settings value.",
+			"type": "string"
+		},
+		"fontVariationSettings": {
+			"description": "CSS font-variation-settings value.",
+			"type": "string"
+		},
+		"lineGapOverride": {
+			"description": "CSS line-gap-override value.",
+			"type": "string"
+		},
+		"sizeAdjust": {
+			"description": "CSS size-adjust value.",
+			"type": "string"
+		},
+		"unicodeRange": {
+			"description": "CSS unicode-range value.",
+			"type": "string"
+		}
+	},
+	"required": [
+		"fontFamily",
+		"src"
+	],
+	"additionalProperties": false
+}
\ No newline at end of file
diff --git a/tests/mu-plugins/mu-plugin.php b/tests/mu-plugins/mu-plugin.php
index 9cb2e23..8743452 100644
--- a/tests/mu-plugins/mu-plugin.php
+++ b/tests/mu-plugins/mu-plugin.php
@@ -2,6 +2,8 @@
 
 namespace WPJsonSchemas;
 
+use Ergebnis\Json\Printer;
+
 use WP_CLI;
 use WP_REST_Request;
 use WP_REST_Response;
@@ -14,6 +16,8 @@
 	return;
 }
 
+require_once dirname( __DIR__, 2 ) . '/vendor/autoload.php';
+
 set_error_handler( function( int $errno, string $errstr, string $errfile = '', int $errline = 0 ) : bool {
 	// This is an @-suppressed error:
 	if ( ! ( error_reporting() & $errno ) ) {
@@ -104,6 +108,50 @@ function save_rest_array( array $data, string $dir ) : void {
 	}
 }
 
+function save_external_schema( string $url, string $name, array $path = [] ) : void {
+	$target = dirname( ABSPATH ) . "/external-schemas/{$name}.json";
+	$schema = download_url( $url );
+
+	if ( is_wp_error( $schema ) ) {
+		throw new \Exception( "Failed to download external {$name} schema." );
+	}
+
+	$file = file_get_contents( $schema );
+
+	if ( ! $file ) {
+		throw new \Exception( "Failed to open {$name} schema file." );
+	}
+
+	$data = json_decode( $file, true );
+
+	if ( ! $data ) {
+		throw new \Exception( "Failed to parse external {$name} schema." );
+	}
+
+	foreach ( $path as $key ) {
+		if ( isset( $data[ $key ] ) ) {
+			$data = $data[ $key ];
+		} else {
+			throw new \Exception( "Failed to find path {$key} in external {$name} schema." );
+		}
+	}
+
+	$json = json_encode( $data, JSON_PRETTY_PRINT ^ JSON_UNESCAPED_SLASHES );
+
+	$printer = new Printer\Printer();
+
+	$json = $printer->print(
+		$json,
+		"\t",
+	);
+
+	$result = file_put_contents( $target, $json );
+
+	if ( ! $result ) {
+		throw new \Exception( "Failed to save external {$name} schema." );
+	}
+}
+
 /**
  * Helper function for performing an internal REST API request and returning its response data.
  *
diff --git a/tests/output/font-collection.php b/tests/output/font-collection.php
index 254d1f5..8c1c558 100644
--- a/tests/output/font-collection.php
+++ b/tests/output/font-collection.php
@@ -8,10 +8,7 @@
 	$data,
 ], 'font-collections' );
 
-$font_collection_schema = download_url( 'https://schemas.wp.org/trunk/font-collection.json' );
-
-if ( is_wp_error( $font_collection_schema ) ) {
-	throw new \Exception( 'Failed to download font-collection schema.' );
-}
-
-rename( $font_collection_schema, dirname( ABSPATH ) . '/external-schemas/font-collection.json' );
+save_external_schema(
+	'https://schemas.wp.org/trunk/font-collection.json',
+	'font-collection'
+);
diff --git a/tests/output/fonts.php b/tests/output/fonts.php
new file mode 100644
index 0000000..89fe94e
--- /dev/null
+++ b/tests/output/fonts.php
@@ -0,0 +1,59 @@
+<?php
+
+namespace WPJsonSchemas;
+
+// Create a font family:
+$family_payload = [
+	'name' => 'Chakra Petch',
+	'fontFamily' => '"Chakra Petch", sans-serif',
+	'slug' => 'chakra-petch',
+	'preview' => 'https://s.w.org/images/fonts/17.7/previews/chakra-petch/chakra-petch.svg',
+];
+$family_response = get_rest_response(
+	'POST',
+	'/wp/v2/font-families',
+	[
+		'font_family_settings' => json_encode( $family_payload ),
+	]
+);
+$family_id = $family_response->data['id'];
+
+// Add a font face to the font family:
+$face_payload = [
+	'src' => content_url( 'uploads/fonts/example.woff2' ),
+	'fontWeight' => '600',
+	'fontStyle' => 'normal',
+	'fontFamily' => 'Chakra Petch',
+	'preview' => 'https://s.w.org/images/fonts/17.7/previews/chakra-petch/chakra-petch-600-normal.svg',
+];
+$face_response = get_rest_response(
+	'POST',
+	"/wp/v2/font-families/{$family_id}/font-faces",
+	[
+		'font_face_settings' => json_encode( $face_payload ),
+	]
+);
+$face_id = $face_response->data['id'];
+
+// Get the font families:
+$data = get_rest_response( 'GET', '/wp/v2/font-families' );
+
+save_rest_array( [
+	$data,
+], 'font-families' );
+
+// Get the faces for the font family:
+$data = get_rest_response( 'GET', "/wp/v2/font-families/{$family_id}/font-faces" );
+
+save_rest_array( [
+	$data,
+], 'font-faces' );
+
+save_external_schema(
+	'https://schemas.wp.org/trunk/theme.json',
+	'font-face',
+	[
+		'definitions',
+		'fontFace',
+	]
+);