API Manager licensing API reference

How your software activates, checks and deactivates API Manager license keys, with request and response details.

Beka Rice Avatar

Written by

Last updated


API Manager answers licensing requests from your software at your store’s root URL. Your software sends a license key, a product ID and an instance ID, and the store replies in JSON with whether the key is activated, how many activations are left and, for updates, a download link. The PHP library does all of this for WordPress plugins and themes; use this reference to build your own client for anything else.

When you’d use this

  • License desktop or mobile apps, SaaS accounts or software that isn’t a WordPress plugin or theme.
  • Check a license from a server, for example before granting access to a service.
  • Debug what the PHP library sends, using Postman.

How requests work

Send a GET or POST request to your store’s root URL with wc-api=wc-am-api and a wc_am_action:

https://example.com/?wc-api=wc-am-api&wc_am_action=activate&api_key=KEY&product_id=456&instance=abc123XYZ&object=customer.example.net&version=1.2.3

Mind the trailing slash on your store URL, so there’s no double slash before the query string. Use HTTPS. Every response is JSON and includes success and api_call_execution_time; errors also include code, error and a data object with error_code and error.

Request keys

KeyWhat it is
wc_am_actionThe action: activate, deactivate, status, information, update, product_list or verify_api_key_is_active.
api_keyThe customer’s user license key or product license key.
product_idThe Licensed product ID from the product’s Licensing tab. For variable products, the variation’s ID. Hard-code it in your software where you can.
instanceA unique ID your software creates for this installation (see below).
objectWhere the key is activated, such as the site’s host name or a device name, without http:// or https://. Recorded with the activation and used by Ignore test activations.
versionThe installed version of your software.
plugin_nameFor WordPress plugins, the plugin folder and main file, such as my-plugin/my-plugin.php. For themes, the theme folder name. Other software can send any value in the same format.
slugFor WordPress plugins and themes, the folder name, such as my-plugin. Optional on update, but recommended.

Older key names are still accepted: license_key for api_key, software_version for version, platform for object, and request for wc_am_action.

Instance IDs

An instance ID identifies one installation. Generate a random, unique string the first time your software activates (the PHP library uses a 12-character password from WordPress), store it, and send it with every request for that installation. Activating again with a new instance ID uses another activation. When the customer deactivates, you can keep the instance ID to reuse if they activate again.

Actions

activate

Activates the key for this instance. Required: api_key, product_id, instance. Optional: object, version (both saved with the activation).

{
  "activated": true,
  "message": "4 out of 5 activations remaining",
  "success": true,
  "data": {
    "unlimited_activations": false,
    "total_activations_purchased": 5,
    "total_activations": 1,
    "activations_remaining": 4
  },
  "api_call_execution_time": "0.057487 seconds"
}

deactivate

Frees the activation for this instance. Required: api_key, product_id, instance. Returns deactivated and the updated activation counts.

status

Reports whether this instance is activated and how many activations remain. Required: api_key, product_id, instance. Optional: version, which updates the version recorded for the activation. status_check is active or inactive, and data.activated is true or false. API Manager checks the license is still valid (not expired, subscription active) before replying.

information

Returns the software’s details from the product’s Metadata and Documents (name, version, author, homepage, requirements, last updated, changelog and other sections), in the shape WordPress’s plugin information screen uses. Required: product_id, plugin_name. To authenticate the request, also send api_key, instance and version.

update

Returns the latest version and, for an authenticated request from an activated installation, a download link in data.package.package. Required: product_id, plugin_name. To authenticate, also send api_key, instance and version; slug is optional. Without an activation that matches api_key, product_id and instance, the response has an empty package, and WordPress reports "Update package not available". The link expires after the store’s URL expire time.

{
  "success": true,
  "data": {
    "package": {
      "id": "my-plugin-456",
      "slug": "my-plugin",
      "plugin": "my-plugin/my-plugin.php",
      "new_version": "1.3.0",
      "url": "https://example.com/product/my-plugin/",
      "tested": "6.8",
      "upgrade_notice": "",
      "package": "https://example.com/?..."
    }
  },
  "api_call_execution_time": "0.049395 seconds"
}

product_list

Lists the products a key can activate, with product IDs, titles and order IDs (and subscription IDs for subscription licenses). Required: api_key, instance. The instance ID here only identifies the cached response; it doesn’t create an activation.

verify_api_key_is_active

Returns success: true if the key exists and belongs to at least one active license. Required: api_key.

Legacy actions

plugininformation and pluginupdatecheck are the information and update actions with serialized PHP responses, for the PHP library before version 2.0. Don’t use them in new software.

Error messages

Errors return "success": false with the message in error:

MessageCause
"The following required query string data is missing: …"A required key is empty or missing.
"No licensing resources exist. Login to My Account to verify there are activations remaining, and the license key and product ID are correct."No active license matches the key and product ID.
"No licensing resources exist. Login to My Account to verify there are activations remaining, and the license key is correct."From product_list: no active license matches the key.
"Cannot activate license key. No licensing resources available."No activations are left.
"Cannot activate license key. The license key has already been activated with the same unique instance ID sent with this request."That instance is already activated.
"The license key could not be deactivated."No activation matches the key, product ID and instance.
"The license key is not active or does not exist."From verify_api_key_is_active.
"A customer account does not exist for this license key."The key doesn’t exist on this store: it was mistyped, or it was replaced.
"The access for this license key has been disabled, or a license key was sent that does not exist on this store."The customer’s user license key is disabled on their user profile, so none of their keys work.
"The product ID … could not be found in this store."From information and update: the product ID isn’t a licensing product.
"The source did not send a required IP address." / "The source is not trusted."Trusted sources are set and the request didn’t match.
"Request value does not exist."Unknown wc_am_action.

In the full responses, links to My Account are included as HTML. Troubleshoot API Manager explains how to fix each one for a customer.

Staging and local activations

With Ignore test activations on (the default), an activate request whose object is a staging or local development address, such as *.local, *.test or a host’s staging domain, succeeds without being stored or counted. Send the site’s host name as object so your store can tell. Updates work as usual.

Trusted sources

To accept requests only from known servers, list their IP addresses in wp-config.php:

define( 'WC_AM_TRUSTED_SOURCES', array( '192.0.2.10', '2001:db8::10' ) );

Every request must then include ip_address with the server’s IP. API Manager checks both that value and the IP the request came from against the list, and rejects the request unless both match. If your servers sit behind a load balancer or proxy, make sure the request’s IP reaches your store as one of the listed addresses.

Caching and performance

API Manager caches license lookups and responses to keep API requests fast, and refreshes the cache when licenses, orders or products change.

  • define( 'WC_AM_ENABLE_CACHE', false ); in wp-config.php turns that caching off, which helps while you develop and test against live data.
  • API Manager sends no-cache headers on your home page, where requests arrive. define( 'WC_AM_DISABLE_HOMEPAGE_CACHE', false ); stops that, for stores that want their home page cached; then make sure your page cache or CDN never caches requests with wc-api=wc-am-api in the query string.

Firewalls and security services that block query strings or automated requests can break the API, so allow requests to ?wc-api=wc-am-api.

Test with Postman

The PHP library repository on GitHub includes a Postman collection with every action. Import it, set your store URL and the keys for a test license, and send requests to see the full responses. Turn on Server error log under API Manager » Configuration » Debug to see the store’s side.

Common issues

Requests return the home page instead of JSON

A cache, CDN or firewall answered the request, or rewrote its query string. Exclude wc-api=wc-am-api from caching and security rules.

Responses include PHP notices

WP_DEBUG_DISPLAY is printing notices into the response, which breaks the JSON. Turn debug display off on your store.

Activation works but update checks fail

update and information need plugin_name, and an authenticated update also needs version and the same instance used to activate. Check the request in the Server error log.

Keep learning