releases.sh

JSON Schema layer prepares schemas for REST clients, frontends, and AI tools

v7.1

1 featureThis release1 featureNew capabilitiesAI-tallied from the release notes
From the original release noteView original ↗

WordPress 7.1 introduces a shared JSON Schema preparation layer for schemas exposed to REST clients, frontend applications, and AI tools.

WordPress accepts several internal schema conventions that are useful during server-side validation but are not portable JSON Schema draft-04. Passing these schemas directly to external validators could cause validation errors or expose PHP callbacks and other server-only implementation details.

  1. The wp_prepare_json_schema_for_client() function
    1. Compatibility guidance
    2. Choosing a schema profile
  2. Schema transformations
    1. Required properties use Draft 4 syntax
    2. Server-only keywords are removed
    3. Empty object defaults are represented as objects
  3. Allowed keywords filter
  4. Abilities REST API changes
  5. AI Client integration
    1. Follow-up
  6. Related ticket

The wp_prepare_json_schema_for_client() function

The new wp_prepare_json_schema_for_client() function converts a WordPress schema into a portable, client-facing representation before it is exposed to REST clients, frontend applications, AI tools, or other external consumers.

Most developers do not need to take action. Core now applies this preparation automatically to:

  • Abilities API schemas exposed through REST responses.
  • Ability input schemas converted into AI Client function declarations.
$prepared_schema = wp_prepare_json_schema_for_client( $schema );

This keeps the schemas used by clients (REST clients, JavaScript applications, and AI tools) consistent. See ticket #64955 and changeset [62591].

Compatibility guidance

This change is primarily automatic. Existing ability registration and execution code does not need to call the new function.

Call wp_prepare_json_schema_for_client() directly when a plugin exposes a WordPress-style schema outside the server-side PHP validation boundary, for example through:

  • a custom REST endpoint;
  • a JavaScript configuration object;
  • an MCP tool declaration;
  • an AI function declaration; or
  • another external schema consumer.

Do not replace the schema stored by an ability with the prepared version. Keep the canonical WordPress schema for server-side use and prepare a copy only when sending it to a client.

Choosing a schema profile

This new function accepts a schema and an optional schema profile:

/** 
 * Prepares a JSON Schema for clients.
 * 
 * @param array<string, mixed> $schema         The schema array.
 * @param string               $schema_profile Optional. Name of the schema
 *                                             profile whose keywords should be
 *                                             preserved. Default 'draft-04'.
 * @return array<string, mixed> The prepared schema.
 */
wp_prepare_json_schema_for_client(
	array $schema,
	string $schema_profile = 'draft-04'
): array

WordPress provides two schema profiles out of the box:

  • draft-04 is the default. Use it when publishing a standalone schema to general-purpose clients, including Ability metadata, frontend validators, MCP integrations, and AI tooling. It preserves the broader JSON Schema Draft 4 vocabulary, including composition and reference keywords such as $ref, definitions, allOf, not, dependencies, and additionalItems.
  • rest-api uses the narrower keyword set supported by WordPress REST API route schemas. Use it when preparing a schema that must follow the same conventions as a REST route’s argument or response schema.
// General client-facing or Ability schema.
$prepared_schema = wp_prepare_json_schema_for_client( $schema );

// Schema intended to match WordPress REST API conventions.
$prepared_rest_schema = wp_prepare_json_schema_for_client(
	$schema,
	'rest-api'
);

Both profiles produce JSON Schema Draft 4 output. The difference is the set of keywords retained in the prepared schema.

What is JSON Schema Draft 4?

“Draft 4” refers to the fourth published draft of the JSON Schema specification, which defines a JSON-based contract for describing and validating JSON data. See the JSON Schema Draft 4 core specification for its terminology and behaviour.

Schema transformations

Preparation is recursive and applies to nested object properties, array items, composition keywords, definitions, dependencies, and other subschemas.

Required properties use Draft 4 syntax

WordPress schemas may mark individual properties as required:

'properties' => array(
	'title' => array(
		'type'     => 'string',
		'required' => true,
	),
)

The prepared schema moves those property names into the containing object’s Draft 4 required array:

'required' => array( 'title' ),

The property-level boolean is then removed.

If the object already has a valid required array, that array takes precedence over property-level boolean values. A property-level required => false is removed without creating an empty required array.

A boolean required value on a scalar schema is also removed because it has no Draft 4 equivalent.

This preparation only affects schemas sent to clients. It does not change the server-side behaviour of rest_validate_value_from_schema() or WP_Ability::validate_input().

Example of transforming schema:

$schema = array(
	'type'       => 'object',
	'properties' => array(
		'title'   => array(
			'type'              => 'string',
			'required'          => true,
			'sanitize_callback' => 'sanitize_text_field',
		),
		'content' => array(
			'type'              => 'string',
			'validate_callback' => 'is_string',
		),
	),
);

$prepared_schema = wp_prepare_json_schema_for_client( $schema );

The prepared schema is equivalent to:

array(
	'type'       => 'object',
	'required'   => array( 'title' ),
	'properties' => array(
		'title'   => array(
			'type' => 'string',
		),
		'content' => array(
			'type' => 'string',
		),
	),
);

The original $schema is not modified.

Server-only keywords are removed

PHP callbacks and other WordPress-specific keywords cannot be represented meaningfully in JSON. The preparation process removes unsupported keywords, including:

  • sanitize_callback
  • validate_callback
  • arg_options

These keywords are removed recursively, including when they appear inside:

  • properties
  • patternProperties
  • definitions
  • dependencies
  • items
  • additionalItems
  • additionalProperties
  • anyOf
  • oneOf
  • allOf
  • not

The callbacks remain available in the original server-side schema. They are removed only from its client-facing representation.

Ability authors should also note that validate_callback and sanitize_callback are not executed by the Abilities API’s runtime validation. Custom ability validation should use the wp_ability_validate_input and wp_ability_validate_output filters introduced in WordPress 7.1.

Empty object defaults are represented as objects

In PHP, an empty array serializes to [], even when its schema declares an object:

array(
	'type'    => 'object',
	'default' => array(),
)

For client-facing schemas, the empty default is prepared so that JSON serialization produces an object:

{
	"type": "object",
	"default": {}
}

This prevents client validators from rejecting the default because its serialized type does not match the declared object type.

Allowed keywords filter

wp_prepare_json_schema_for_client() uses wp_get_json_schema_allowed_keywords() to decide which keywords to preserve.

The broader draft-04 profile can preserve composition and documentation keywords such as:

  • $ref
  • definitions
  • allOf
  • not
  • dependencies
  • additionalItems

Preserving a keyword means that it may be included in the client-facing schema. It does not mean that WordPress validates or sanitizes values against that keyword on the server.

The allowed keyword list is filterable:

add_filter(
	'wp_json_schema_allowed_keywords',
	function ( $keywords, $schema_profile ) {
		if ( 'draft-04' === $schema_profile ) {
			$keywords[] = 'x-example-keyword';
		}

		return $keywords;
	},
	10,
	2
);

Custom keywords should only be exposed when the receiving clients are known to understand them.

Abilities REST API changes

WordPress now prepares an ability’s input and output schemas before including them in Abilities REST API responses.

For abilities registered with REST visibility, consumers of endpoints under:

/wp-json/wp-abilities/v1/abilities

receive portable schemas instead of the original WordPress-internal schema arrays.

This is an output-boundary transformation:

  • WP_Ability::get_input_schema() and WP_Ability::get_output_schema() continue to return the original schemas to server-side PHP.
  • REST responses contain prepared versions.
  • Ability execution and server-side validation remain unchanged.

Developers comparing a schema retrieved directly from a WP_Ability object with one returned through REST may therefore see intentional differences.

AI Client integration

When the WordPress AI Client converts abilities into function declarations, it now prepares each ability’s input schema first:

$input_schema = wp_prepare_json_schema_for_client(
	$ability->get_input_schema()
);

This prevents WordPress-only schema keywords and nonportable required conventions from being passed directly into AI function declarations.

The helper prepares a portable Draft 4 schema; it is not a provider-specific compiler. Individual AI providers may support a smaller schema vocabulary or impose additional requirements. Provider-specific adaptation may therefore still occur elsewhere in the integration.

Follow-up

Provider-specific adaptation is tracked in WordPress/php-ai-client#256: each provider should be able to override the input schema for its own API requirements, which differ across providers and evolve over time.

Related ticket

  • #64955 — Add schema compiler for AI tool calling compatibility
  • Changeset [62591] — Abilities API: Reuse JSON Schema client preparation
  • Changeset [62549] — REST API: Add a shared helper for JSON Schema allowed keywords.
  • Changeset [62449] — Abilities API: Normalize required schema shape for REST responses

Props to @jorbin for peer review and suggested improvements.

#abilities-api, #7-1, #dev-notes, #dev-notes-7-1, #rest-api

Fetched July 31, 2026

JSON Schema layer prepares schemas for REST clients,… — releases.sh