Prepare, expose, and audit WordPress-authored JSON Schemas with the WordPress 7.1 JSON Schema API. Covers wp_prepare_json_schema_for_client, wp_get_json_schema_allowed_keywords, draft-04 versus rest-api profiles, required-property conversion, recursive schema cleanup, empty-object defaults, the wp_json_schema_allowed_keywords filter, and the boundary between schema publication, REST validation, sanitization, and application authorization. Use when returning schemas through REST, Abilities, AI...
Scanned 9/5/2026
Install to Claude Code
npx -y skills add Lonsdale201/wp-agent-skills --skill wp-json-schema-api --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Wp Json Schema Api?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/lonsdale201-wp-json-schema-api)More formats (shields.io, HTML) on the badges page.
---
name: wp-json-schema-api
description: >-
Prepare, expose, and audit WordPress-authored JSON Schemas with the WordPress
7.1 JSON Schema API. Covers wp_prepare_json_schema_for_client,
wp_get_json_schema_allowed_keywords, draft-04 versus rest-api profiles,
required-property conversion, recursive schema cleanup, empty-object
defaults, the wp_json_schema_allowed_keywords filter, and the boundary
between schema publication, REST validation, sanitization, and application
authorization. Use when returning schemas through REST, Abilities, AI tools,
JavaScript configuration, or converting WordPress REST-style schemas for
external consumers.
license: GPLv2-or-later
metadata:
wp-skills-author: "Soczó Kristóf"
wp-skills-contact: "mailto:lonsdale201@hotmail.com"
wp-skills-plugin: "wordpress"
wp-skills-plugin-version-tested: "7.1"
wp-skills-wp-version-tested: "7.1"
wp-skills-php-min: "7.4"
wp-skills-last-updated: "2026-08-20"
---
# WordPress JSON Schema API
WordPress 7.1 adds a shared API for preparing WordPress-authored schemas for
clients. Its job is compatibility and safe publication: it converts a few
WordPress conventions and removes keywords outside the selected profile. It
does not validate or sanitize a value and does not authorize an operation.
## Use the public helpers
Feature-detect when WordPress 7.0 or older remains supported:
```php
if ( function_exists( 'wp_prepare_json_schema_for_client' ) ) {
$public_schema = wp_prepare_json_schema_for_client( $schema, 'draft-04' );
} else {
// Keep a deliberately maintained compatibility schema; do not expose
// callbacks or blindly return the server schema.
$public_schema = $legacy_public_schema;
}
```
The two public functions have deliberately different defaults:
- `wp_get_json_schema_allowed_keywords()` defaults to `rest-api`;
- `wp_prepare_json_schema_for_client()` defaults to `draft-04`.
Choose `rest-api` for the historical REST-exposed keyword subset. Choose
`draft-04` for a standalone client, Ability description, or AI provider that
can consume the broader Draft 4 vocabulary. An unknown profile falls back to
the REST keyword set; do not rely on misspelled profile names failing closed
with an exception.
## Keep server and published schemas separate
```php
$server_schema = array(
'type' => 'object',
'properties' => array(
'post_id' => array(
'type' => 'integer',
'minimum' => 1,
'required' => true,
'sanitize_callback' => 'absint',
),
),
);
$public_schema = wp_prepare_json_schema_for_client(
$server_schema,
'draft-04'
);
```
The published result moves the per-property `required: true` marker into the
parent object's `required` array and strips the callable. Keep the original
schema for WordPress execution and the prepared copy for transport.
If the parent already has a Draft 4 `required` array, it takes precedence:
per-property booleans are removed but are not merged into that array. Make the
server contract internally consistent before publishing it.
## Understand what preparation changes
Preparation recursively walks schema-bearing keywords, removes keys not
allowed by the profile, and normalizes WordPress-specific representations. In
particular:
- an empty array used as the default of an object schema becomes a JSON object;
- per-property boolean `required` flags are removed and, when no parent
`required` array exists, the `true` properties are collected there;
- a stray boolean `required` without an object property list is removed;
- nested `properties`, `patternProperties`, `definitions`, `dependencies`,
`items`, `not`, `additionalProperties`, `additionalItems`, `anyOf`, `oneOf`,
and `allOf` schemas are prepared recursively when the chosen profile permits
those keywords;
- unknown and WordPress-only keys, including PHP callbacks, are removed.
Numeric arrays used as data, such as property-dependency lists, are preserved
instead of being mistaken for schema maps.
Read `references/profiles-and-normalization.md` for the exact profile delta and
review probes.
## Validation, sanitization, and authorization remain separate
Never treat a prepared schema as evidence that input was checked:
1. validate inbound data with the API that owns the request, such as
`rest_validate_value_from_schema()` or the registered REST argument schema;
2. sanitize/coerce only according to that server contract;
3. perform capability and object-ownership checks separately;
4. copy allowlisted fields into the write model rather than mass-assigning a
request object.
Adding a keyword through `wp_json_schema_allowed_keywords` only allows that
keyword to survive publication. It does not teach WordPress validators or
sanitizers how to enforce it. A plugin that adds `const`, `if`, or a custom
keyword must also own and test the corresponding validation behavior.
## Filter safely
The filter receives the allowed keyword list and profile name:
```php
add_filter(
'wp_json_schema_allowed_keywords',
static function ( array $keywords, string $profile ): array {
if ( 'draft-04' !== $profile ) {
return $keywords;
}
$keywords[] = 'x-acme-ui';
return array_values( array_unique( $keywords ) );
},
10,
2
);
```
Only extend the list for a namespaced, documented consumer contract. A global
filter affects every schema prepared later in the request, including core and
other plugins. Keep it deterministic, avoid removing standard keywords, and
test for cross-plugin collisions.
## Review checklist
- Confirm the target consumer and select `rest-api` or `draft-04` explicitly.
- Keep the execution schema distinct from its prepared transport copy.
- Inspect the prepared output with `wp_json_encode()`, especially empty object
defaults and nested schemas.
- Verify parent `required` arrays and per-property markers do not disagree.
- Confirm no callable, internal metadata, secret default, or implementation
detail survives publication.
- Validate and authorize actual inputs independently of schema preparation.
- Test custom allowed-keyword filters with other plugins active.
- Feature-detect the helpers or require WordPress 7.1.
## Related skills
- `wp-rest-api` for server route schemas and request validation.
- `wp-abilities-api` for Ability input/output contracts.
- `wp-ai-client` for structured AI output and function declarations.
## References
- WordPress 7.1 core: `wp-includes/json-schema.php`.
- WordPress REST schema helpers: `wp-includes/rest-api.php`.
- <https://make.wordpress.org/core/2026/07/31/json-schema-preparation-for-client-compatibility-in-wordpress-7-1/>
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!