do_action( 'xmlrpc_call', string $name, array|string $args, wp_xmlrpc_server $server )
- Since
- 2.5.0, 5.7.0
Fires for every authenticated XML-RPC request, exposing the method name, its escaped arguments, and the server instance for inspection or blocking. The $server parameter was only added in 5.7.0, so callbacks written for older sites may register with just two accepted arguments. Because it's an action, returning a value from a callback does nothing; stopping a method requires calling die() or triggering an IXR error inside the callback. Pair it with xmlrpc_enabled if the goal is to turn XML-RPC off entirely rather than police individual methods.
Description
All built-in XML-RPC methods use the action xmlrpc_call, with a parameter equal to the method's name, e.g., wp.getUsersBlogs, wp.newPost, etc.
Compatibility
- WordPress
- since 5.7.0
- 6.7.7
- 6.8.8
- 6.9.7
- 7.0.4
- 7.1.0
Present in every tracked release (6.7.7 to 7.1.0).
Parameters
$namestring- The method name.
$argsarray|string- The escaped arguments passed to the method.
$serverwp_xmlrpc_server- The XML-RPC server instance.
Code examples
Every example is editable and runs in a real WordPress booted in your browser by WordPress Playground. Press Run, then edit the code: clicking away re-runs it. Nothing is sent anywhere until you do.
Log which XML-RPC method name triggered a request
Register a callback and then simulate an authenticated XML-RPC call so the hook fires and prints its arguments.
add_action( 'xmlrpc_call', 'wppaste_log_xmlrpc_method', 10, 3 );
function wppaste_log_xmlrpc_method( $name, $args, $server ) {
printf(
'Method called: %s using a %s server instance.',
esc_html( $name ),
esc_html( get_class( $server ) )
);
}
require_once ABSPATH . WPINC . '/class-wp-xmlrpc-server.php';
$server = new wp_xmlrpc_server();
do_action( 'xmlrpc_call', 'wp.getUsersBlogs', array(), $server );This calls do_action() directly to demonstrate the hook, since the browser sandbox never actually posts to xmlrpc.php; in production the same callback fires on real requests without this manual trigger.
Block a specific XML-RPC method such as pingback.ping
Check the method name inside the callback and short-circuit the ones you want to refuse, a common way to stop pingback abuse.
add_action( 'xmlrpc_call', 'wppaste_block_pingback', 10, 1 );
function wppaste_block_pingback( $name ) {
if ( 'pingback.ping' === $name ) {
echo esc_html( "Blocked XML-RPC method: {$name}" ) . '<br>';
return;
}
echo esc_html( "Allowed XML-RPC method: {$name}" ) . '<br>';
}
require_once ABSPATH . WPINC . '/class-wp-xmlrpc-server.php';
$server = new wp_xmlrpc_server();
do_action( 'xmlrpc_call', 'pingback.ping', array(), $server );
do_action( 'xmlrpc_call', 'wp.getUsersBlogs', array(), $server );In a live plugin you would normally call wp_die() or throw an IXR_Error after the echo so the offending method never actually runs.
Common problems and fixes · 4
- Why doesn't my xmlrpc_call callback ever run on a live site?
- Why does my callback only receive two arguments instead of three?
- Why is $args sometimes an array and sometimes a string?
- Can I stop the XML-RPC method from running by returning false from this hook?
Why doesn't my xmlrpc_call callback ever run on a live site?
Why does my callback only receive two arguments instead of three?
Why is $args sometimes an array and sometimes a string?
Can I stop the XML-RPC method from running by returning false from this hook?
Alternatives and related functions
xmlrpc_enabled- When the goal is to disable XML-RPC entirely rather than inspect or block one method at a time.
xmlrpc_methods- When you need to add or remove entire method names from the XML-RPC method table before any request is handled.
wp_xmlrpc_server_class- When you need to swap in a custom server class instead of reacting to individual method calls.
xmlrpc_pingback_error- When the concern is specifically pingback error responses rather than general method auditing.
Where this hook fires · 67
wp-includes/class-wp-xmlrpc-server.php:744wp_xmlrpc_server::wp_getUsersBlogs()wp-includes/class-wp-xmlrpc-server.php:1358wp_xmlrpc_server::wp_newPost()wp-includes/class-wp-xmlrpc-server.php:1759wp_xmlrpc_server::wp_editPost()wp-includes/class-wp-xmlrpc-server.php:1842wp_xmlrpc_server::wp_deletePost()wp-includes/class-wp-xmlrpc-server.php:1943wp_xmlrpc_server::wp_getPost()wp-includes/class-wp-xmlrpc-server.php:2004wp_xmlrpc_server::wp_getPosts()wp-includes/class-wp-xmlrpc-server.php:2103wp_xmlrpc_server::wp_newTerm()wp-includes/class-wp-xmlrpc-server.php:2208wp_xmlrpc_server::wp_editTerm()wp-includes/class-wp-xmlrpc-server.php:2324wp_xmlrpc_server::wp_deleteTerm()wp-includes/class-wp-xmlrpc-server.php:2403wp_xmlrpc_server::wp_getTerm()wp-includes/class-wp-xmlrpc-server.php:2468wp_xmlrpc_server::wp_getTerms()wp-includes/class-wp-xmlrpc-server.php:2575wp_xmlrpc_server::wp_getTaxonomy()wp-includes/class-wp-xmlrpc-server.php:2633wp_xmlrpc_server::wp_getTaxonomies()wp-includes/class-wp-xmlrpc-server.php:2719wp_xmlrpc_server::wp_getUser()wp-includes/class-wp-xmlrpc-server.php:2782wp_xmlrpc_server::wp_getUsers()wp-includes/class-wp-xmlrpc-server.php:2862wp_xmlrpc_server::wp_getProfile()wp-includes/class-wp-xmlrpc-server.php:2912wp_xmlrpc_server::wp_editProfile()wp-includes/class-wp-xmlrpc-server.php:3001wp_xmlrpc_server::wp_getPage()wp-includes/class-wp-xmlrpc-server.php:3044wp_xmlrpc_server::wp_getPages()wp-includes/class-wp-xmlrpc-server.php:3099wp_xmlrpc_server::wp_newPage()wp-includes/class-wp-xmlrpc-server.php:3136wp_xmlrpc_server::wp_deletePage()wp-includes/class-wp-xmlrpc-server.php:3205wp_xmlrpc_server::wp_editPage()wp-includes/class-wp-xmlrpc-server.php:3268wp_xmlrpc_server::wp_getPageList()wp-includes/class-wp-xmlrpc-server.php:3329wp_xmlrpc_server::wp_getAuthors()wp-includes/class-wp-xmlrpc-server.php:3373wp_xmlrpc_server::wp_getTags()wp-includes/class-wp-xmlrpc-server.php:3423wp_xmlrpc_server::wp_newCategory()wp-includes/class-wp-xmlrpc-server.php:3510wp_xmlrpc_server::wp_deleteCategory()wp-includes/class-wp-xmlrpc-server.php:3567wp_xmlrpc_server::wp_suggestCategories()wp-includes/class-wp-xmlrpc-server.php:3613wp_xmlrpc_server::wp_getComment()wp-includes/class-wp-xmlrpc-server.php:3669wp_xmlrpc_server::wp_getComments()
… and 37 more locations
Source code
* @since 5.7.0 Added the `$args` and `$server` parameters. * * @param string $name The method name. * @param array|string $args The escaped arguments passed to the method. * @param wp_xmlrpc_server $server The XML-RPC server instance. */ do_action( 'xmlrpc_call', 'wp.getUsersBlogs', $args, $this ); $blogs = (array) get_blogs_of_user( $user->ID ); $struct = array(); $primary_blog_id = 0; $active_blog = get_active_blog_for_user( $user->ID );Changelog
Introduced in 2.5.0. Unchanged from 6.7.7 through 7.1.0.
Signature, return type and hooks compared across 5 parsed releases.
$args and $server parameters.from the docblockAbout this page
- Parsed data
- Generated from the wordpress-develop 6.9.7 tag, 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.