WordPress 7.1 introduces `wp_prepare_json_schema_for_client()` with `draft-04` and `rest-api` profiles. It can move property-level boolean `required` values into the parent object's required array and recursively strip server-only callbacks. Plugins that expose Abilities or schemas to JavaScript and AI clients need to prove the prepared copy is portable while the original server schema remains unchanged.
Use this for plugin authors, REST API developers, Abilities API integrations, block-editor tools, AI clients, generated forms, SDKs, and test teams preparing for WordPress 7.1.
Quick answer
Build one fixture that contains nested objects, arrays, required properties, defaults, enums, sanitize callbacks, validate callbacks, unsupported keywords, and reused schema variables. Prepare it under both profiles, compare normalized output to a stored contract, validate representative payloads in the client, then assert the original PHP array is byte-for-byte equivalent to its pre-call snapshot.
What to check first
- Inventory every schema passed to REST routes, Abilities, block data, JavaScript clients, AI tooling, generated forms, SDK code, and documentation, including schemas returned through filters.
- Create fixtures with top-level and nested required fields, arrays of objects, nullable values, enums, defaults, descriptions, formats, additional properties, and both sanitization and validation callbacks.
- Run `wp_prepare_json_schema_for_client()` with the default Draft 4 profile and the REST API profile, then diff keys, required arrays, callback removal, nesting, ordering, and serialized output.
- Validate valid, missing-required, wrong-type, extra-property, null, boundary, and deeply nested payloads using the same client library that consumes production schemas.
- Snapshot the original server schema before preparation, invoke server validation and sanitization after preparation, and prove the original callbacks and behavior remain available.
Diagnostic table
Use this table to keep the work practical. It connects the symptom to evidence and a verification step.
| Action | Evidence to collect | How to verify |
| Inventory exported schemas | Inventory every schema passed to REST routes, Abilities, block data, JavaScript clients, AI tooling, generated forms, SDK code, and documentation, including schemas returned through filters. | Prepared output contains object-level required arrays for every intended required property. |
| Build nested compatibility fixtures | Create fixtures with top-level and nested required fields, arrays of objects, nullable values, enums, defaults, descriptions, formats, additional properties, and both sanitization and validation callbacks. | No callable, closure, or server-only callback appears anywhere in the serialized client schema. |
| Compare both preparation profiles | Run `wp_prepare_json_schema_for_client()` with the default Draft 4 profile and the REST API profile, then diff keys, required arrays, callback removal, nesting, ordering, and serialized output. | The production client accepts valid fixtures and rejects the planned invalid fixtures with useful field paths. |
| Contract-test the actual client | Validate valid, missing-required, wrong-type, extra-property, null, boundary, and deeply nested payloads using the same client library that consumes production schemas. | Server validation and sanitization still execute from the original schema after repeated preparation calls. |
Why this usually happens
- WordPress REST schemas historically used property-level conventions that generic JSON Schema clients do not interpret the same way.
- PHP callbacks are executable server concerns and cannot be serialized safely for a browser or remote AI client.
- A shallow copy or in-place mutation can strip callbacks from later server validation.
- Different client validators can implement formats, defaults, or unsupported keywords differently.
Useful command or data shape
Adapt paths, IDs, and privacy handling to the site before running commands or storing data on production.
$server_schema = my_plugin_schema();
$before = serialize( $server_schema );
$client_schema = wp_prepare_json_schema_for_client(
$server_schema,
array( 'profile' => 'draft-04' )
);
assert( serialize( $server_schema ) === $before );
// Contract-test $client_schema in the real consumer.
Safe fix order
Do the work in a sequence that makes each result easy to prove. Stop if a step produces new evidence that changes the incident scope.
- Inventory exported schemas
- Build nested compatibility fixtures
- Compare both preparation profiles
- Contract-test the actual client
- Prove the server schema is unchanged
Decision rule
Pass when each exported client schema validates representative payloads under its declared profile, required fields survive at every level, server-only callbacks are absent from the copy, and the original server schema plus behavior remain unchanged.
What to tell the client or owner
Give the owner the affected versions, exact workflow, observed result, business impact, evidence location, temporary control, named owner, and next review time. Remove credentials and personal data from shared screenshots and logs.
Production verification checklist
- Prepared output contains object-level required arrays for every intended required property.
- No callable, closure, or server-only callback appears anywhere in the serialized client schema.
- The production client accepts valid fixtures and rejects the planned invalid fixtures with useful field paths.
- Server validation and sanitization still execute from the original schema after repeated preparation calls.
Mistakes to avoid
- Do not change several plugins, cache rules, firewall settings, or integrations before preserving a baseline.
- Do not treat one successful browser test as proof for APIs, retries, alternate clients, background jobs, or mixed-version fleets.
- Do not paste secrets, personal data, complete production payloads, or customer records into tickets, screenshots, or long-lived logs.
- Do not close the test until the final user-visible state and the server-side evidence agree.
Questions teams ask during testing
Should plugins replace their server schema with the prepared copy?
No. Keep the original schema for server validation and prepare a separate client-facing copy.
Is Draft 4 the only profile?
No. The dev note documents Draft 4 as the default and also provides a REST API compatibility profile.
When HandL WP should help
Bring in HandL WP when a production checkout, form, editor, security gate, performance incident, or attribution workflow is at risk. We can preserve evidence, isolate the failing layer, make the smallest corrective change, and verify the result across WordPress, connected services, logs, and the user journey.
If this is active on a production site, test a WordPress 7.1 plugin schema.
Related HandL WP guides
Use these related guides when the same issue touches tracking, security, checkout, or crawler visibility.
Helpful references