In order to route all requests to api.wordpress.org APIs to a custom service, we first need to mirror the WordPress core, plugin and theme SVN repositories.
WP.org hosts the API at api.wordpress.org (documented in the old wiki) which is accessed by WP installations via HTTP on older servers that can’t do latest HTTPS crypto or upgraded to HTTPS requests on all other server.
API Source Code
Most of the source code for the api.wordpress.org endpoints is available in the “meta” SVN repository which is also mirrored on GitHub.
API Endpoints
WordPress contains the following hard-coded API endpoints in the source code. All of the update endpoints use POST requests with a very dynamic payload for each site (hard to cache) that includes all of the installed components (i.e. themes, plugins, translations) and their versions along with the site URL and other meta data.
Core API Endpoints
Source for the main core/version-check endpoint is not public!
core/credits/1.1/(source)core/browse-happy/1.1/(source)core/serve-happy/1.0/(source)core/importers/1.1/(source)core/checksums/1.0/(source)core/version-check/1.7/(source)POSTrequest withwp_install(network site URL or home URL) andwp_blog(home URL) headers.
Plugin API Endpoints
Served by plugin-directory plugin.
Theme API Endpoints
Translations API Endpoints
translations/plugins/1.0/(source)translations/themes/1.0/(source)translations/core/1.0/(source)
Patterns API Endpoints
patterns/1.0/(source)GETrequest.
Miscellaneous API Endpoints
secret-key/1.1/salt/(source and source) —GETrequest with no payload.events/1.0/(source) —GETrequest with WP versionuser-agentand location arguments.core/handbook/1.0/(source and source) front-end only (not called by the server)
How to Rewrite WordPress.org API Requests
Use the http_api_curl filter to rewrite the URLs of the WP.org API requests to your own custom endpoint:
add_action(
'http_api_curl',
function ( $handle, $parsed_args, $url ) {
$hostname_map = [
// REPLACE these with your own hostnames.
'api.wordpress.org' => 'reverse.example.net/wp-api',
'downloads.wordpress.org' => 'reverse.example.net/wp-downloads',
];
// Attempt to rewrite the request hostname.
$url_replaced = str_replace(
array_keys( $hostname_map ),
array_values( $hostname_map ),
$url
);
if ( $url_replaced !== $url ) {
curl_setopt( $handle, CURLOPT_URL, $url_replaced );
}
},
1000,
3
);
This can be placed in a custom plugin or must-use plugin to get applied globally.
