How to Replace WordPress Update API for Core, Plugins and Themes

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/ (sourcePOST request with wp_install (network site URL or home URL) and wp_blog (home URL) headers.

Plugin API Endpoints

Served by plugin-directory plugin.

  • plugins/info/1.2/ (source)
  • plugins/update-check/1.1/ (sourcePOST request.

Theme API Endpoints

  • themes/info/1.2/ (source)
  • themes/update-check/1.1/ (source)

Translations API Endpoints

  • translations/plugins/1.0/ (source)
  • translations/themes/1.0/ (source)
  • translations/core/1.0/ (source)

Patterns API Endpoints

  • patterns/1.0/ (sourceGET request.

Miscellaneous API Endpoints

  • secret-key/1.1/salt/ (source and source) — GET request with no payload.
  • events/1.0/ (source) — GET request with WP version user-agent and 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.