Claude Skill

wp-json-schema-api

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-objec

LLM Mart · 0 points · 0 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download lonsdale201-wp-agent-skills-wordpress_wp-json-schema-api-52f6020.zip · 4 KB
Part of lonsdale201/wp-agent-skills — 226 skills

Install

skills CLI npx skills add https://github.com/Lonsdale201/wp-agent-skills/tree/main/wordpress/wp-json-schema-api
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install lonsdale201-wp-agent-skills@llmmart
Git git clone https://github.com/Lonsdale201/wp-agent-skills.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole lonsdale201/wp-agent-skills collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

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:

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

$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:

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

Files (wp-agent-skills)
  • agents
    • openai.yaml 226 B
      interface:
        display_name: "WordPress JSON Schema API"
        short_description: "Prepare safe client schemas with WordPress 7.1"
        default_prompt: "Use $wp-json-schema-api to prepare or audit this WordPress JSON Schema contract."
      
  • references
    • profiles-and-normalization.md 1.9 KB
      # JSON Schema profiles and normalization
      
      ## Profile matrix
      
      Both profiles include the historical REST schema keywords returned by
      `rest_get_allowed_schema_keywords()`: descriptive fields, type/format/enum,
      object and array shape, numeric/string/array limits, and `anyOf` / `oneOf`.
      
      The `draft-04` profile additionally preserves:
      
      - `$schema`, `id`, and `$ref`;
      - parent-array `required`;
      - `allOf` and `not`;
      - `definitions` and `dependencies`;
      - `additionalItems`.
      
      The preparer only filters and normalizes the schema. Preservation is not a
      claim that `rest_validate_value_from_schema()` implements every preserved
      Draft 4 keyword.
      
      ## Before and after probe
      
      Input:
      
      ```php
      $schema = array(
      	'type'       => 'object',
      	'default'    => array(),
      	'properties' => array(
      		'name' => array(
      			'type'              => 'string',
      			'required'          => true,
      			'sanitize_callback' => 'sanitize_text_field',
      		),
      		'note' => array(
      			'type'     => 'string',
      			'required' => false,
      		),
      	),
      );
      
      $prepared = wp_prepare_json_schema_for_client( $schema, 'draft-04' );
      ```
      
      Expected properties of the result:
      
      - `default` is an object when encoded to JSON;
      - parent `required` is `array( 'name' )`;
      - neither property retains a boolean `required`;
      - `sanitize_callback` is absent.
      
      Do not compare the object default to an array with strict equality. Confirm the
      transport representation instead:
      
      ```php
      $json = wp_json_encode( $prepared );
      ```
      
      ## Failure probes
      
      - Pass an unknown profile and confirm it uses the REST subset.
      - Supply an existing parent `required` array and confirm it remains unchanged.
      - Nest object schemas in `items`, `additionalProperties`, and `oneOf` and check
        that private keys are removed recursively.
      - Add a keyword through `wp_json_schema_allowed_keywords`; confirm it survives
        output but is not magically enforced by REST validation.
      - Run the same filter beside another extension to detect request-global
        allowlist changes.
      
  • SKILL.md 6.5 KB
    ---
    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/>
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related