
The original design of the API Manager was providing API key management and software updates for WordPress plugins and themes specifically. Over time, this expanded to include software, services, and more.
Query string keys like plugin_name
and slug
are intended for WordPress plugins and themes, but when you’re managing other types of software, any values can be used. The API will return a download URL and version info as needed for update checks.
Client software sends a query string in an HTTP(s) request to the API Manager using either POST or GET. The query string contains a series of keys and values.
Note: Postman is recommended for remote API testing.
Description of keys sent in HTTP(s) API requests:
↑ Back to top- instance – A unique alphanumeric string that is not repeated.
- product_id or parent product ID – A positive integer that corresponds to a real product in the WooCommerce store.
- api_key – A unique alphanumeric string that is not repeated, and is in authenticated requests. There are two main types: master license key and product license key.
- plugin_name
- WordPress Plugin: The lowercase name of the plugin directory, a forward slash, then the name of the root file. For example:Â
search-engine-ping/search-engine-ping
or optionallysearch-engine-ping/search-engine-ping.php
with the .php ending. - WordPress Theme: The lowercase name of the theme directory, a forward slash, then the lowercase name of the plugin directory. For example:
search-engine-ping/search-engine-ping
. - Non WordPress Software: Use something with a similar format.
- WordPress Plugin: The lowercase name of the plugin directory, a forward slash, then the name of the root file. For example:Â
- version – An iterative version of a software release, service, or some other product. Used for WordPress plugin update requests.
- object – Used to identify where the API Key is being activated from. The object could be a server, smart phone, or anything capable of sending an HTTP(s) request.
- slug – The lowercase name of the plugin/theme directory. For example:
search-engine-ping
.
Note: WordPress plugins and themes require the ‘plugin_name’ and ‘slug’ keys and values depending on the API request. non WordPress software can send fake data formatted as if it were WordPress software.
To ensure smooth activation and update delivery, always use the latest version of both the PHP library and the WooCommerce API Manager.
Best practice: Always pass the product_id
as a hardcoded value with your API requests. This avoids activation errors for your customers.
You can pass the parent product ID instead if you would like to allow your users to switch between license tiers from within variable products. This makes it easy to manage licenses across variations (like when using subscription switching) without requiring users to re-download a file or replace their key.
The WooCommerce API Manager PHP Library for Plugins and Themes fully supports passing the parent product ID for variable products. This simplifies license management and avoids common activation issues.
What is an instance ID?
↑ Back to topAn instance ID is a unique code your software or device creates when activating an API Key for the first time. It works like a password—unique, private, and tied to that specific activation.
For example, if you’re selling a WordPress plugin, each activation of that plugin will create its own instance ID. That same ID is used for all related API requests, like checking the activation status.
When the user deactivates their license, you can either delete the instance ID or save it for re-use if they activate again later. If you activate again with a new ID, it will count as a new activation.
The instance ID is used:
- When you activate a license
- For all API requests related to that activation
- Until the license is deactivated
Each activation needs a new, unique instance ID.
You can create the instance ID however you want. In our PHP Library, we use WordPress’s built-in password generator to do it.
Trusted Sources
↑ Back to topYou can restrict API access by IP address using the WC_AM_TRUSTED_SOURCES
constant. This lets you whitelist specific servers.
How to set it up:
- In your
wp-config.php
, add something like this:
define( 'WC_AM_TRUSTED_SOURCES', array( '192.168.1.1', '2001:0db8:85a3::8a2e:0370:7334' ) );
- Any API request must now include a query string key:
ip_address
, set to the server’s IP. - The API Manager checks two things:
- The
ip_address
sent in the query string - The actual IP that made the request. Both must match a value in your trusted list.
- The
Why use this?
This is helpful if you run a remote service (like a membership system) that needs to call your WooCommerce site for license validation or updates. It keeps unauthorized systems out, even if they have an API key.
If you use a load balancer or proxy, make sure it passes a valid IP address from the trusted list.
HTTP(S) Requests to API Endpoints
↑ Back to topThe API Manager listens for API requests at the root URL of the web site. For example the root URL might be https://www.toddlahman.com/. The forward slash at the end of the URL should be taken into account when building the query string so that there is not a double forward slash (//) between the root URL and the query string. The endpoint used to connect to the APIs is wc-api as the key, and the value is wc-am-api, so the query string would start as the following:
https://wc/?wc-api=wc-am-api
At the end of this URL + query string any added keys and values would be added using ampersand (&), so it would look something like this:
https://wc/?wc-api=wc-am-api&key=value
The key and value would be replaced with something like &product_id=19
. The ampersand (&) cancontenates the next key=value to the query string.
The next key and value is wc_am_action={value}
. Below is a list of values for the wc_am_action key.
Each action, such as activate, deactivate, etc., is an API Endpoint that performs specific actions detailed in sections below.
- wc_am_action=activate
- wc_am_action=deactivate
- wc_am_action=status
- wc_am_action=product_list
- wc_am_action=verify_api_key_is_active
- wc_am_action=information
- wc_am_action=update
- wc_am_action=plugininformation (Deprecated: for legacy use only)
- wc_am_action=pluginupdatecheck (Deprecated: for legacy use only)
To build on the URL + query string we could add a request to activate an API Key such that:
https://wc/?wc-api=wc-am-api&wc_am_action=activate
More would need to be added to the query string to provide all the required information to activate the API Key.
Next is a list of the request values with additional required keys each API endpoint requires, along with other details.
wc_am_action=activate
↑ Back to topPurpose: To activate an API Key that will then allow access to one or more API resources depending on the API Key type.
Response format: JSON
Required keys:Â api_key, product_id, instance.
Optional keys: object, version. (These values will be recorded in the database for this activation.)
Example query string:
https://wc/?wc-api=wc-am-api&wc_am_action=activate&instance=p1uOusaNM5ub3&object=dev.toddlahman.com/&product_id=62912&version=1.0&api_key=448567cf667c299bb706df6fe64ed2b44c7d37ba
Note: if the object value is defined as a URL, remote the http:// or https://, since some server security will mangle the entire query string, and break it as a result.
Example JSON success response:
{ "activated": true, "message": "0 out of 4 activations remaining", "success": true, "data": { "unlimited_activations": false, "total_activations_purchased": 4, "total_activations": 4, "activations_remaining": 0 }, "api_call_execution_time": "0.057487 seconds" }
Example JSON error response:
{ "code": "100", "error": "Cannot activate API Key. The API Key has already been activated with the same unique instance ID sent with this request.", "success": false, "data": { "error_code": "100", "error": "Cannot activate API Key. The API Key has already been activated with the same unique instance ID sent with this request." }, "api_call_execution_time": "0.027128 seconds" }
wc_am_action=deactivate
↑ Back to topPurpose: To deactivate an API Key so the API Key.
Response format: JSON
Required keys:Â api_key, product_id, instance.
Example query string:
https://wc/?wc-api=wc-am-api&wc_am_action=deactivate&instance=p1uOusaNM5ub3&product_id=62912&api_key=448567cf667c299bb706df6fe64ed2b44c7d37ba
Example JSON success response:
{ "deactivated": true, "activations_remaining": "1 out of 4 activations remaining", "success": true, "data": { "unlimited_activations": false, "total_activations_purchased": 4, "total_activations": 3, "activations_remaining": 1 }, "api_call_execution_time": "0.062482 seconds" }
Example JSON error response:
{ "code": "100", "error": "The API Key could not be deactivated.", "success": false, "data": { "error_code": "100", "error": "The API Key could not be deactivated." }, "api_call_execution_time": "0.023881 seconds" }
wc_am_action=status
↑ Back to topPurpose: Returns the status of an API Key activation. Default data returned for product_id includes total activations purchased, total activations, activations remaining, and if the API Key is activated.
Response format: JSON
Required keys:Â api_key, product_id, instance.
Optional key: version. (The version will be updated when the HTTP request is received.)
Note: If the return value for status_check
is active
, or for activated
is true
, then the time limit has not expired and the API Key is still active. If this is for a subscription, then the subscription is still active. The API Manager verifies the API Key activation should still exists, and deletes it if it should not, due to an expired time limit or inactive subscription, before returning a response.
Example query string:
https://wc/?wc-api=wc-am-api&wc_am_action=status&instance=p1uOusaNM5ub3&product_id=62912&api_key=448567cf667c299bb706df6fe64ed2b44c7d37ba
Example JSON success response:
Product ID: 141198
API Key activated.
{ "status_check": "active", "success": true, "data": { "unlimited_activations": false, "total_activations_purchased": 23, "total_activations": 1, "activations_remaining": 22, "activated": true, "api_key_expirations": { "non_wc_subs_resources": [ { "friendly_api_key_expiration_date": "September 29, 2022 5:29 am", "number_of_expiring_activations": "3", "product_title": "Simple Product (no subscription)", "order_id": "141504", "product_id": "141198" }, { "friendly_api_key_expiration_date": "September 29, 2022 7:07 am", "number_of_expiring_activations": "6", "product_title": "Simple Product (no subscription)", "order_id": "141507", "product_id": "141198" }, { "friendly_api_key_expiration_date": "October 14, 2022 10:37 am", "number_of_expiring_activations": "5", "product_title": "Simple Product (no subscription)", "order_id": "141523", "product_id": "141198" }, { "friendly_api_key_expiration_date": "September 25, 2022 4:25 pm", "number_of_expiring_activations": "6", "product_title": "Simple Product (no subscription)", "order_id": "141501", "product_id": "141198" }, { "friendly_api_key_expiration_date": "October 12, 2022 12:10 pm", "number_of_expiring_activations": "3", "product_title": "Simple Product (no subscription)", "order_id": "141526", "product_id": "141198" } ], "non_wc_subs_resources_total": 5, "wc_subs_resources_total": 0 } }, "api_call_execution_time": "0.001539 seconds" }
Product ID: 141198
API Key not activated.
{ "status_check": "inactive", "success": true, "data": { "unlimited_activations": false, "total_activations_purchased": 28, "total_activations": 0, "activations_remaining": 28, "activated": false, "api_key_expirations": { "non_wc_subs_resources": [ { "friendly_api_key_expiration_date": "September 29, 2022 5:29 am", "number_of_expiring_activations": "3", "product_title": "Simple Product (no subscription)", "order_id": "141504", "product_id": "141198" }, { "friendly_api_key_expiration_date": "September 29, 2022 7:07 am", "number_of_expiring_activations": "6", "product_title": "Simple Product (no subscription)", "order_id": "141507", "product_id": "141198" }, { "friendly_api_key_expiration_date": "October 14, 2022 10:37 am", "number_of_expiring_activations": "5", "product_title": "Simple Product (no subscription)", "order_id": "141523", "product_id": "141198" }, { "friendly_api_key_expiration_date": "September 25, 2022 4:25 pm", "number_of_expiring_activations": "6", "product_title": "Simple Product (no subscription)", "order_id": "141501", "product_id": "141198" }, { "friendly_api_key_expiration_date": "October 12, 2022 5:10 am", "number_of_expiring_activations": "4", "product_title": "Simple Product (no subscription)", "order_id": "141526", "product_id": "141198" }, { "friendly_api_key_expiration_date": "October 15, 2022 12:16 am", "number_of_expiring_activations": "4", "product_title": "Simple Product (no subscription)", "order_id": "141535", "product_id": "141198" } ], "non_wc_subs_resources_total": 6, "wc_subs_resources_total": 0 } }, "api_call_execution_time": "0.095696 seconds" }
Product ID: 32960
API Key not activated.
{
"status_check": "inactive",
"success": true,
"data": {
"unlimited_activations": false,
"total_activations_purchased": 7,
"total_activations": 0,
"activations_remaining": 7,
"activated": false,
"api_key_expirations": {
"wc_subs_resources": [
{
"friendly_api_key_expiration_date": "Not yet ended",
"number_of_expiring_activations": "3",
"product_title": "Simple Comments - WooCommerce and WordPress Form Protection",
"order_id": "141531",
"sub_id": "141532",
"product_id": "32960"
},
{
"friendly_api_key_expiration_date": "Not yet ended",
"number_of_expiring_activations": "4",
"product_title": "Simple Comments - WooCommerce and WordPress Form Protection",
"order_id": "141526",
"sub_id": "141528",
"product_id": "32960"
}
],
"non_wc_subs_resources_total": 0,
"wc_subs_resources_total": 2
}
},
"api_call_execution_time": "0.184801 seconds"
}
Example JSON error response:
{ "code": "100", "error": "No API resources exist.", "success": false, "data": { "error_code": "100", "error": "No API resources exist." }, "api_call_execution_time": "0.011719 seconds" }
wc_am_action=product_list
↑ Back to topPurpose: Returns a unique and ordered list of Product IDs, Product Titles, Order IDs, and Sub IDs if the product is a WooCommerce Subscription.
Response format: JSON
Required keys: api_key, instance. (Although a unique Instance ID is required, it is only used with other elements to uniquely cache the response for one hour, and is not associated with an API Key activation.)
Example query string:
https://wc/?wc-api=wc-am-api&wc_am_action=product_list&api_key=b9dc373c7983cda3897c1502574b1bf929e02a53&instance=p1uOusaNM5ub3
Example JSON success response:
{ "success": true, "data": { "product_list": { "wc_subs_resources": [ { "product_title": "Simple Comments - WooCommerce and WordPress Form Protection", "order_id": "141526", "sub_id": "141528", "product_id": "32960" }, { "product_title": "Simple Comments - WooCommerce and WordPress Form Protection", "order_id": "141493", "sub_id": "141494", "product_id": "32961" }, { "product_title": "Simple Comments - WooCommerce and WordPress Form Protection", "order_id": "141512", "sub_id": "141513", "product_id": "32962" }, { "product_title": "Simple Comments - WooCommerce and WordPress Form Protection", "order_id": "141495", "sub_id": "141496", "product_id": "137886" }, { "product_title": "Simple Comments - WooCommerce and WordPress Form Protection", "order_id": "141529", "sub_id": "141530", "product_id": "140516" } ], "non_wc_subs_resources": [ { "product_title": "Variable Product (no subscription)", "order_id": "141526", "product_id": "141186" }, { "product_title": "Simple Product (no subscription)", "order_id": "141504", "product_id": "141198" } ], "non_wc_subs_resources_total": 2, "wc_subs_resources_total": 5 } }, "api_call_execution_time": "0.00181 seconds" }
wc_am_action=verify_api_key_is_active
↑ Back to topPurpose: Returns success true if the API Key exists and is assigned to an active API Resource.
Response format: JSON
Required keys: api_key.
Example query string:
https://wc/?wc-api=wc-am-api&wc_am_action=verify_api_key_is_active&api_key=b9dc373c7983cda3897c1502574b1bf929e02a53
Example JSON success response:
{ "success": true, "api_call_execution_time": "0.095668 seconds" }
Example JSON error response:
{ "code": "100", "error": "The API Key is not active or does not exist.", "success": false, "data": { "error_code": "100", "error": "The API Key is not active or does not exist." }, "api_call_execution_time": "0.003622 seconds" }
wc_am_action=information
↑ Back to topPurpose: Data returned depends on if the request was authenticated or not.
Response format: JSON
Required keys if authenticating: api_key, product_id, plugin_name, instance, version.
Example query string:
https://wc/?wc-api=wc-am-api&wc_am_action=information&instance=p1uOusaNM5ub3&product_id=62912&version=1.0&api_key=448567cf667c299bb706df6fe64ed2b44c7d37ba&plugin_name=search-engine-ping/search-engine-ping.php
Note: For plugin_name
requirements see Description of keys sent in HTTP(s) API requests.
Example JSON success response:
{ "success": true, "data": { "package": { "product_id": "62912" }, "info": { "name": "Search Engine Ping", "active_installs": 4, "version": "1.4", "slug": "search-engine-ping/search-engine-ping.php", "author": "Todd Lahman LLC", "homepage": "https://wc/shop/search-engine-ping/", "requires": "3.5", "tested": "4.2", "last_updated": "2015-04-21", "compatibility": "4.2", "sections": { "changelog": "<h4>2017.1.9 - Version 1.3.8.4</h4>..." } } }, "api_call_execution_time": "0.034218 seconds" }
Example JSON error response:
{ "code": "100", "error": "The product ID 62912222 could not be found in this store.", "success": false, "data": { "error_code": "100", "error": "The product ID 62912222 could not be found in this store." }, "api_call_execution_time": "0.001816 seconds" }
Required keys if not authenticating: product_id, plugin_name.
Example query string:
https://wc/?wc-api=wc-am-api&wc_am_action=information&product_id=62912&plugin_name=search-engine-ping/search-engine-ping.php
Note: For plugin_name
requirements see Description of keys sent in HTTP(s) API requests.
Example JSON success response:
{ "success": true, "data": { "info": { "name": "Search Engine Ping", "version": "1.4", "slug": "search-engine-ping/search-engine-ping.php", "author": "Todd Lahman LLC", "homepage": "https://wc/shop/search-engine-ping/", "requires": "3.5", "tested": "4.2", "last_updated": "2015-04-21", "compatibility": "4.2", "sections": { "changelog": "<h4>2017.1.9 - Version 1.3.8.4</h4>..." } } }, "api_call_execution_time": "0.018425 seconds" }
Example JSON error response:
{ "code": "100", "error": "The product ID 629122 could not be found in this store.", "success": false, "data": { "error_code": "100", "error": "The product ID 629122 could not be found in this store." }, "api_call_execution_time": "0.001346 seconds" }
wc_am_action=update
↑ Back to topPurpose: Returns whether a software update is available. If the request is authenticated with an instance ID, then the URL to the file download is returned.
Response format: JSON
Required keys if authenticating: api_key, product_id, plugin_name, instance, version.
Optional key: slug. (slug is optional, but preferred.)
Example query string:
https://wc/?wc-api=wc-am-api&wc_am_action=update&instance=p1uOusaNM5ub3&product_id=62912&version=1.0&api_key=448567cf667c299bb706df6fe64ed2b44c7d37ba&plugin_name=search-engine-ping/search-engine-ping.php&slug=search-engine-ping
Note: For plugin_name
requirements see Description of keys sent in HTTP(s) API requests.
Example JSON success response:
Note: package
is the file download URL.
{ "success": true, "data": { "package": { "product_id": "62912", "id": "search-engine-ping-62912", "slug": "search-engine-ping", "plugin": "search-engine-ping/search-engine-ping.php", "new_version": "1.4", "url": "https://wc/shop/search-engine-ping/", "tested": "4.2", "upgrade_notice": "", "package": "https://s3.amazonaws.com/..." } }, "api_call_execution_time": "0.049395 seconds" }
Example JSON error response:
{ "code": "100", "error": "The product ID 629122 could not be found in this store.", "success": false, "data": { "error_code": "100", "error": "The product ID 629122 could not be found in this store." }, "api_call_execution_time": "0.001345 seconds" }
Required keys if not authenticating: product_id, plugin_name.
Example query string:
https://wc/?wc-api=wc-am-api&wc_am_action=update&product_id=62912&plugin_name=search-engine-ping/search-engine-ping.php
Note: For plugin_name
requirements see Description of keys sent in HTTP(s) API requests.
Example JSON success response:
{ "success": true, "data": { "package": { "id": "search-engine-ping-62912", "slug": "search-engine-ping", "plugin": "search-engine-ping/search-engine-ping.php", "new_version": "1.4", "url": "https://wc/shop/search-engine-ping/", "tested": "4.2", "upgrade_notice": "", "package": "" } }, "api_call_execution_time": "0.010199 seconds" }
Example JSON error response:
{ "code": "100", "error": "The product ID 629122 could not be found in this store.", "success": false, "data": { "error_code": "100", "error": "The product ID 629122 could not be found in this store." }, "api_call_execution_time": "0.001348 seconds" }
wc_am_action=plugininformation
↑ Back to topResponse format: serialized
Same as wc_am_action=information, except the response format is serialized, which is required to work with WordPress plugin and theme update requests that use the pre-2.0 API Manager PHP Library.
wc_am_action=pluginupdatecheck
↑ Back to topResponse format: serialized
Same as wc_am_action=update, except the response format is serialized, which is required to work with WordPress plugin and theme update requests that use the pre-2.0 API Manager PHP Library.