Registers a new ability using the Abilities API. It requires three steps:
Description
<ol> <li>Hook into the wp_abilities_api_init action.</li> <li>Call wp_register_ability() with a namespaced name and configuration.</li> <li>Provide execute and permission callbacks.</li> </ol> Example: function my_plugin_register_abilities(): void {
wp_register_ability(
'my-plugin/analyze-text',
array(
'label' => __( 'Analyze Text', 'my-plugin' ),
'description' => __( 'Performs sentiment analysis on provided text.', 'my-plugin' ),
'category' => 'text-processing',
'input_schema' => array(
'type' => 'string',
'description' => __( 'The text to be analyzed.', 'my-plugin' ),
'minLength' => 10,
'required' => true,
),
'output_schema' => array(
'type' => 'string',
'enum' => array( 'positive', 'negative', 'neutral' ),
'description' => __( 'The sentiment result: positive, negative, or neutral.', 'my-plugin' ),
'required' => true,
),
'execute_callback' => 'my_plugin_analyze_text',
'permission_callback' => 'my_plugin_can_analyze_text',
'meta' => array(
'annotations' => array(
'readonly' => true,
),
'public' => true,
),
)
);
}
add_action( 'wp_abilities_api_init', 'my_plugin_register_abilities' ); <h3>Naming Conventions</h3> Ability names must follow these rules: <ul> <li>Include a namespace prefix (e.g., my-plugin/my-ability).</li> <li>Use only lowercase alphanumeric characters, dashes, and forward slashes.</li> <li>Use descriptive, action-oriented names (e.g., process-payment, generate-report).</li> </ul> <h3>Categories</h3> Abilities must be organized into categories. Ability categories provide better discoverability and must be registered before the abilities that reference them: function my_plugin_register_categories(): void {
wp_register_ability_category(
'text-processing',
array(
'label' => __( 'Text Processing', 'my-plugin' ),
'description' => __( 'Abilities for analyzing and transforming text.', 'my-plugin' ),
)
);
}
add_action( 'wp_abilities_api_categories_init', 'my_plugin_register_categories' ); <h3>Input and Output Schemas</h3> Schemas define the expected structure, type, and constraints for ability inputs and outputs using JSON Schema syntax. They serve two critical purposes: automatic validation of data passed to and returned from abilities, and self-documenting API contracts for developers. WordPress implements a validator based on a subset of the JSON Schema Version 4 specification (<a href="https://json-schema.org/specification-links.html#draft-4">https://json-schema.org/specification-links.html#draft-4</a>).For details on supported JSON Schema properties and syntax, see the related WordPress REST API Schema documentation: <a href="https://developer.wordpress.org/rest-api/extending-the-rest-api/schema/#json-schema-basics">https://developer.wordpress.org/rest-api/extending-the-rest-api/schema/#json-schema-basics</a> Defining schemas is mandatory when there is a value to pass or return.They ensure data integrity, improve developer experience, and enable better documentation: 'input_schema' => array(
'type' => 'string',
'description' => __( 'The text to be analyzed.', 'my-plugin' ),
'minLength' => 10,
'required' => true,
),
'output_schema' => array(
'type' => 'string',
'enum' => array( 'positive', 'negative', 'neutral' ),
'description' => __( 'The sentiment result: positive, negative, or neutral.', 'my-plugin' ),
'required' => true,
), <h3>Callbacks</h3> <h4>Execute Callback</h4> The execute callback performs the ability's core functionality. It receives optional input data and returns either a result or WP_Error on failure. function my_plugin_analyze_text( string $input ): string|WP_Error {
$score = My_Plugin::perform_sentiment_analysis( $input );
if ( is_wp_error( $score ) ) {
return $score;
}
return My_Plugin::interpret_sentiment_score( $score );
} <h4>Permission Callback</h4> The permission callback determines whether the ability can be executed.It receives the same input as the execute callback and must return a boolean or WP_Error. Common use cases include checking user capabilities, validating API keys, or verifying system state: function my_plugin_can_analyze_text( string $input ): bool|WP_Error {
return current_user_can( 'edit_posts' );
} <h3>Client Exposure</h3> Set the high-level public flag to make an ability available to clients such as the REST API, MCP, or AI agents: 'meta' => array(
'public' => true,
), The public flag seeds the default for each per-channel flag. For the REST API it seeds show_in_rest, which lets the ability be invoked via HTTP requests. Set a per-channel flag directly to override that default. For example, keep a public ability out of the REST API: 'meta' => array(
'public' => true,
'show_in_rest' => false,
),
Parameters
$namestring
The name of the ability. Must be a namespaced string containing a prefix, e.g., my-plugin/my-ability. Can only contain lowercase alphanumeric characters, dashes, and forward slashes.
$argsarray
Return
WP_Ability|null
The registered ability instance on success, null on failure.
Uses · 5
doing_action()Returns whether or not an action hook is currently being processed.
290functionwp_register_ability(string$name,array$args):?WP_Ability{291if(!doing_action('wp_abilities_api_init')){292_doing_it_wrong(293__FUNCTION__,294sprintf(295/* translators: 1: wp_abilities_api_init, 2: string value of the ability name. */296__('Abilities must be registered on the %1$s action. The ability %2$s was not registered.'),297'<code>wp_abilities_api_init</code>',298'<code>'.esc_html($name).'</code>'299),300'6.9.0'301);302returnnull;303}304305$registry=WP_Abilities_Registry::get_instance();306if(null===$registry){307returnnull;308}309310return$registry->register($name,$args);311}
History
Introduced in 6.9.0. Unchanged from 6.9.7 through 7.1.0.
Signature, return type and hooks compared across 3 parsed releases.
About this page
Parsed data
Generated from the wordpress-develop 7.1.0 tag, from src/wp-includes/abilities-api.php, and regenerated for each WordPress release so it tracks the code rather than a snapshot of it.
Corrections
Something wrong on this page? Report it and it gets fixed in the next regeneration.