🔥WORDPRESS PLUGINS YOU WON'T FIND ANYWHERE ELSE!BloatSlayer🔍SEO Surgeon📦TrackShip🚀LaunchPad🎯CommandPost🔑VeriKeyProofFlow💬SiteChat
Docs › VeriKey

VeriKey Documentation

A complete software licensing system for WordPress plugins and themes. Issue keys, validate activations, manage products, and serve automatic updates from your own server.

Overview

VeriKey is a self-hosted software licensing plugin for WordPress. It gives plugin and theme developers a way to issue license keys, validate them against a specific domain, and manage the full lifecycle of each license from activation through renewal or revocation.

Unlike SaaS licensing platforms that charge per-key or per-month fees, VeriKey runs entirely on your own WordPress installation. You control the data, the API endpoints, and the pricing. The plugin provides a REST API that your distributed software calls home to, a PHP client SDK you can bundle with your plugins, and an optional update server that lets you push new versions to licensed users automatically.

VeriKey supports three tiers internally: Free (basic license creation and validation), Standard (adds product management and the update server), and Agency (adds white-label branding and unlimited products). All tiers use the same core key format: VK-XXXX-XXXX-XXXX-XXXX.

Installation

Download VeriKey from your Boulley Technology account or from the link in your purchase confirmation email. In WordPress, go to Plugins › Add New › Upload Plugin, select the verikey.zip file, and click Install Now. After installation, click Activate.

Once activated, VeriKey appears under Tools › VeriKey in the admin menu. The plugin creates its database tables automatically on activation. These tables store license keys, activation records, products, and release metadata. No manual database setup is required.

VeriKey requires PHP 7.4+ and WordPress 5.8+. It registers its own REST API routes under the /wp-json/verikey/v1/ namespace, so your WordPress installation must have pretty permalinks enabled (anything other than "Plain" in Settings › Permalinks). If you are using plain permalinks, the API will still work but URLs will be less readable.

Creating Licenses

To create a single license key, open the VeriKey dashboard and use the Quick Create form at the top. Select a product (or "General" for unscoped keys), choose a license type (lifetime or annual), and optionally set a customer email. Click Generate Key and VeriKey produces a unique key in the format VK-XXXX-XXXX-XXXX-XXXX, where each segment is a random alphanumeric string.

For bulk operations, click the Bulk Create button. Enter the number of keys to generate (up to 500 at a time), select the product and license type, and click Generate. All keys are created in a single batch and can be exported as a CSV file for distribution to resellers or integration with your store.

Each generated key is stored in the database with a status of inactive until a customer activates it on their site. You can also pre-assign keys to specific customer email addresses during creation, which makes it easy to track who owns which key even before activation.

Tip: If you integrate VeriKey with WooCommerce or Easy Digital Downloads, keys can be generated automatically at checkout and emailed to the customer. See the Integrations section on the VeriKey product page for compatible add-ons.

License Management

The main VeriKey dashboard provides a filterable list of all license keys in your system. By default, it shows all keys sorted by creation date, with the newest first. You can filter the list by status (active, inactive, expired, revoked), by product, or by customer email.

The search bar at the top lets you find a specific key by typing any part of the key string, a customer email, or a domain name. Search is instant and updates the list as you type.

Click any key to open its detail view. From here you can:

  • Edit the customer email, expiration date, or associated product.
  • Revoke the key, which immediately invalidates it. The linked site will see a "license revoked" error on the next validation check.
  • Delete the key permanently. This removes all activation records associated with it.
  • View activation history, which shows every domain that has activated or deactivated this key, with timestamps.

Bulk actions are available from the list view. Select multiple keys using the checkboxes and choose an action from the dropdown: revoke, delete, or export to CSV.

REST API

VeriKey exposes three REST API endpoints that your distributed plugins and themes call to manage license activation. All endpoints accept POST requests with JSON bodies and return JSON responses.

POST /wp-json/verikey/v1/activate

Activates a license key and binds it to the requesting domain. This should be called when the user enters their license key in your plugin's settings page.

curl -X POST https://yoursite.com/wp-json/verikey/v1/activate \ -H "Content-Type: application/json" \ -d '{ "license_key": "VK-A1B2-C3D4-E5F6-G7H8", "product_slug": "my-plugin", "domain": "customerdomain.com" }'

Success response (200):

{ "success": true, "message": "License activated successfully.", "data": { "license_key": "VK-A1B2-C3D4-E5F6-G7H8", "status": "active", "domain": "customerdomain.com", "expires_at": "2027-04-07T00:00:00Z", "product": "my-plugin" } }

Error response (400):

{ "success": false, "error": "license_already_active", "message": "This license is already activated on another domain." }

POST /wp-json/verikey/v1/validate

Checks whether a license key is currently valid for the given domain. Your plugin should call this periodically (e.g., once daily) to confirm the license has not been revoked or expired.

curl -X POST https://yoursite.com/wp-json/verikey/v1/validate \ -H "Content-Type: application/json" \ -d '{ "license_key": "VK-A1B2-C3D4-E5F6-G7H8", "product_slug": "my-plugin", "domain": "customerdomain.com" }'

Success response (200):

{ "success": true, "valid": true, "data": { "status": "active", "expires_at": "2027-04-07T00:00:00Z", "days_remaining": 365 } }

POST /wp-json/verikey/v1/deactivate

Unbinds a license key from its current domain, returning it to inactive status. This allows the customer to move their license to a different site.

curl -X POST https://yoursite.com/wp-json/verikey/v1/deactivate \ -H "Content-Type: application/json" \ -d '{ "license_key": "VK-A1B2-C3D4-E5F6-G7H8", "product_slug": "my-plugin", "domain": "customerdomain.com" }'

Success response (200):

{ "success": true, "message": "License deactivated. It can now be activated on a different domain." }

Client SDK

VeriKey includes a PHP client class (class-verikey-client.php) that you bundle with your plugin or theme. This class handles all communication with your VeriKey server and provides a clean API for checking license status, activating keys, and deactivating keys.

Integration Steps

  1. Copy class-verikey-client.php into your plugin's includes/ directory.
  2. Require the file early in your plugin bootstrap (e.g., in your main plugin file).
  3. Instantiate the client with your server URL, product slug, and an option prefix for storing the key in wp_options.
// In your main plugin file require_once plugin_dir_path( __FILE__ ) . 'includes/class-verikey-client.php'; $license = new VeriKey_Client( array( 'api_url' => 'https://yoursite.com/wp-json/verikey/v1', 'product_slug' => 'my-awesome-plugin', 'option_prefix' => 'my_awesome_plugin', // stored as my_awesome_plugin_license_key, etc. ) );

Checking License Status

if ( $license->is_licensed() ) { // Pro features are unlocked } else { // Show upgrade prompt or limit functionality }

The is_licensed() method checks the locally cached license status first. If the cache has expired (default: 24 hours), it performs a remote validation request to your VeriKey server and updates the cache. This minimizes API calls while ensuring timely detection of revoked or expired licenses.

Activating a Key

$result = $license->activate( 'VK-A1B2-C3D4-E5F6-G7H8' ); if ( $result['success'] ) { // Key activated, pro features unlocked echo 'License activated! Expires: ' . $result['data']['expires_at']; } else { // Show error to user echo 'Activation failed: ' . $result['message']; }

Deactivating a Key

$result = $license->deactivate(); if ( $result['success'] ) { echo 'License deactivated. You can now use this key on another site.'; }
Note: The client class automatically determines the current domain from home_url(). You do not need to pass the domain manually. This ensures the correct domain is sent even in multisite or subdirectory installations.

Products (Standard+)

The Products feature, available on Standard and Agency plans, lets you organize licenses by product. Each product has a name, a unique slug, a current version number, and optional metadata like a description and changelog URL.

To create a product, go to Tools › VeriKey › Products and click Add Product. Enter the product name and slug (the slug must match what your distributed plugin sends in API requests). Set the current version number — this is used by the update server to determine whether an update is available.

Products serve two purposes: they scope license keys so that a key for "Plugin A" cannot be used to activate "Plugin B", and they provide the version and download information needed for the update server. Without products, all keys are treated as general-purpose and can activate any plugin.

Version Management

When you release a new version of your plugin, update the version number on the product page and upload the new release ZIP file. VeriKey stores the file and makes it available to the update server endpoint. You can also add changelog notes that are displayed in the WordPress update notification.

Update Server (Standard+)

VeriKey includes a built-in update server that lets your plugins check for and download updates directly from your WordPress installation. This replaces the need for WordPress.org hosting or a third-party update service.

The update check endpoint is automatically registered at:

GET /wp-json/verikey/v1/update-check?product_slug=my-plugin&version=1.0.0&license_key=VK-XXXX-XXXX-XXXX-XXXX

If a newer version is available and the license key is valid, the endpoint returns update metadata compatible with WordPress's plugins_api and site_transient_update_plugins filters:

{ "name": "My Awesome Plugin", "slug": "my-awesome-plugin", "version": "2.1.0", "download_url": "https://yoursite.com/wp-json/verikey/v1/download?product_slug=my-plugin&key=VK-XXXX", "requires": "5.8", "tested": "6.5", "changelog": "Bug fixes and performance improvements." }

Pointing Your Plugin at VeriKey

In your distributed plugin, hook into the pre_set_site_transient_update_plugins filter to check your VeriKey server for updates. The VeriKey Client SDK provides a helper method for this:

// In your plugin bootstrap $license->enable_auto_updates();

This single method call registers all the necessary WordPress filters. When WordPress checks for plugin updates, your plugin will query VeriKey alongside the standard WordPress.org check. If an update is found and the license is valid, it appears in the regular Dashboard › Updates screen just like any other plugin update.

Domain Binding

VeriKey uses a one-key-one-domain binding model. When a license key is activated, it is bound to the domain that made the activation request. Subsequent activation attempts from a different domain will be rejected with a "license already active" error.

The domain is extracted from the domain field in the API request (sent automatically by the Client SDK using home_url()). Subdomains are treated as distinct domains, so shop.example.com and example.com require separate keys.

To move a license to a different domain, the customer must first deactivate it from the current site. This can be done from the plugin's settings page (which calls the deactivate API) or by the admin from the VeriKey dashboard. Once deactivated, the key returns to inactive status and can be activated on any domain.

Note: localhost and staging domains (e.g., staging.example.com) are treated like any other domain. If your customers frequently use staging environments, consider offering multi-domain keys in a future release or providing separate staging keys.

Auto-Expiry

Each license key has an expiration date that determines how long it remains valid. VeriKey supports two license duration types:

  • Lifetime — The key never expires. The expires_at field is set to null and validation always returns valid (assuming the key is not revoked).
  • Annual — The key expires exactly one year from the activation date. After expiration, validation returns "valid": false with a "status": "expired" response. The customer must renew to regain access.

Expiration is checked on every validation request. VeriKey also runs a daily WordPress cron job that scans for newly expired keys and updates their status from "active" to "expired" in the database. This ensures that even if a customer's site never makes a validation request, the key status remains accurate in your dashboard.

When a key expires, the bound domain is not automatically released. The customer must either renew (which extends the expiration date) or deactivate the key to free it. This prevents a scenario where an expired key is activated on a different domain before the original customer has a chance to renew.

License Activation

VeriKey itself requires a license to unlock Standard and Agency features like Products, the Update Server, and white-label branding. The free version provides core license creation, validation, and the REST API without any key.

To activate your VeriKey license, go to Tools › VeriKey › License. Enter the license key from your Boulley Technology purchase (format: VK-XXXX-XXXX-XXXX-XXXX) and click Activate. The key is validated against the Boulley Technology license server and bound to your domain.

If you need to move VeriKey to a different WordPress installation, deactivate the license first from the License tab. You can also manage your license from the Boulley Technology account portal, including deactivating remotely if you no longer have access to the original site.

Troubleshooting

API Returning 404

If requests to /wp-json/verikey/v1/ return a 404 error, flush your permalinks by going to Settings › Permalinks and clicking Save Changes (you do not need to change anything). This forces WordPress to regenerate rewrite rules. If you are using plain permalinks, switch to "Post name" or any other pretty permalink structure, as VeriKey's REST routes require URL rewriting.

Key Not Validating

If a valid key returns an error during activation or validation, check the following:

  • The product_slug in the request matches the product slug configured in VeriKey.
  • The key has not already been activated on a different domain. Check the key's activation history in the VeriKey dashboard.
  • The key has not expired. Check the expires_at field in the key detail view.
  • The key has not been revoked by an admin.

Domain Mismatch

Domain mismatch errors occur when the domain sent in the API request does not match the domain the key was originally activated on. This commonly happens when a site is migrated to a new URL without deactivating the license first. To resolve it, deactivate the key from the VeriKey admin dashboard (click the key, then click Force Deactivate), then have the customer re-activate on the new domain.

Updates Not Showing

If the update server is configured but updates do not appear in WordPress, verify that: the product version in VeriKey is higher than the installed version, a release ZIP has been uploaded, and the license key is valid and active. Also check that $license->enable_auto_updates() is called in your plugin bootstrap. WordPress caches update checks for 12 hours, so you may need to click Check Again on the Updates page.

FAQ

Can I use VeriKey to license non-WordPress software?
VeriKey's REST API is standard HTTP/JSON, so any software that can make HTTP requests can use it for license validation. However, the Client SDK is PHP-specific and WordPress-aware. For non-WordPress applications, you would call the API endpoints directly using your language's HTTP client. The activate, validate, and deactivate endpoints work identically regardless of the calling platform.
How secure are the license keys?
License keys are generated using cryptographically secure random functions (random_bytes in PHP). Each key is unique and practically impossible to guess or brute-force. API communication should always happen over HTTPS to prevent keys from being intercepted in transit. Keys are stored as plain text in the database since they are intended to be shared with customers, but activation records and domain bindings add an additional layer of protection.
Can a customer use the same key on staging and production?
By default, each key binds to a single domain. If your customer needs to use the key on both a staging and production site, you would need to issue two keys or have them deactivate and reactivate when switching. Some developers choose to add a domain whitelist to their client SDK that bypasses validation for localhost and common staging patterns.
What happens when a license expires?
When a license expires, validation requests return "valid": false with a status of "expired". It is up to your plugin to decide how to handle this. Common approaches include disabling pro features while keeping the plugin functional, showing a renewal notice in the admin, or continuing to work in a read-only mode. VeriKey does not force any specific behavior on expiration.
Does VeriKey work with WordPress Multisite?
Yes. VeriKey can be network-activated or activated on individual subsites. When used as a licensing server on a multisite, it operates on the subsite where it is activated. The Client SDK in your distributed plugin detects the correct domain using home_url(), which returns the subsite URL in a multisite context, so each subsite is treated as a separate domain for licensing purposes.
BT
BT Assistant Ask me anything!