Learn how to build a custom Update API to deliver secure, versioned plugin updates. Master the WordPress update process to automate deployments for your customers.
Previously in this course, we built a Licensing Infrastructure: Secure Remote Verification for WordPress Plugins to gate access to our premium features. Now that we can verify customer entitlements, we need to deliver the code itself. This lesson adds the final piece of the distribution puzzle: building a custom Update API to notify WordPress sites of new versions and facilitate seamless, secure plugin updates.
WordPress checks for updates by firing the site_transient_update_plugins filter. Every time the dashboard updates its update transients (usually every 12 hours), it triggers this hook. Our goal is to intercept this request, check our remote server for a newer version, and inject our plugin's update metadata if a newer version exists.
To build a robust system, your update server should behave like the official WordPress.org API. When a request hits your endpoint, it provides the current plugin version and the site's license key.
Sequence diagram: participant Site as WordPress Site; participant API as Update Server; Site → API: GET /check-update version, license; API → API: Verify License & Version; API → Site: JSON new_version, package_url, changelog; Site → Site: Displays "Update Available"; Site → API: Download Request authorized; API → Site: Plugin ZIP file
On the client side (inside your plugin), you need a Service Provider that listens for the update transient check. You shouldn't hardcode this; it should be handled via a dedicated UpdateManager class.
PHPnamespace KnowledgeBase\Services; class UpdateManager { private $api_url = 'https:#6A9955">//updates.yourdomain.com/v1/'; private $plugin_slug = 'knowledge-base/knowledge-base.php'; public function __construct() { add_filter('site_transient_update_plugins', [$this, 'check_for_updates']); } public function check_for_updates($transient) { if (empty($transient->checked)) return $transient; $response = wp_remote_get($this->api_url . 'check', [ 'body' => [ 'version' => $transient->checked[$this->plugin_slug], 'license' => get_option('kb_license_key') ] ]); if (is_wp_error($response) || wp_remote_retrieve_response_code($response) !== 200) { return $transient; } $data = json_decode(wp_remote_retrieve_body($response)); if (version_compare($data->new_version, $transient->checked[$this->plugin_slug], '>')) { $transient->response[$this->plugin_slug] = (object) [ 'slug' => 'knowledge-base', 'plugin' => $this->plugin_slug, 'new_version' => $data->new_version, 'package' => $data->download_url, #6A9955">// Must be a secure, expiring URL 'url' => $data->changelog_url ]; } return $transient; } }
The package URL is the most critical part. Never expose a static link to your ZIP file. If a user shares that link, anyone can download your premium code.
new_version, download_url, and changelog_url.KnowledgeBase plugin, register the UpdateManager service.update_plugins transient in wp_options via delete_site_transient('update_plugins');.site_transient_update_plugins filter runs frequently. If your API is slow, you'll degrade site performance. Always cache your remote API response for at least 12 hours.package key to be a direct URL to a .zip file. If you use a redirect, ensure your server follows it correctly and that the final URL ends in .zip (WordPress enforces this).plugin_slug: If the slug in your API response doesn't match the folder structure of your plugin (e.g., knowledge-base/knowledge-base.php), the update will fail to unzip correctly.We've bridged our plugin to a custom distribution server. By leveraging the site_transient_update_plugins filter, we provide a native WordPress experience for our customers while maintaining total control over licensing and versioning. This completes the distribution architecture we began in the earlier modules.
Up next: Documentation Systems — we'll automate the generation of API docs and user manuals directly from your codebase.
Master the art of plugin deployment. Learn how to sanitize your folder structure, build a professional readme.txt, and prepare your plugin for distribution.
Read moreLearn to extend the WordPress REST API by registering custom endpoints. We'll show you how to securely serve your Knowledge Base data as structured JSON.
Automated Update API
Custom Hooks for React