Software Licensing API

The API included with the Software Licensing extension allows you to remotely activate license keys, check if keys are valid (and not expired), and also retrieve information about the latest versions of software.

There are four API request types available:

  • activate_license - Used to remotely activate a license key
  • deactivate_license - Used to remotely deactivate a license key
  • check_license - Used to remotely check if a license key is activated, valid, and not expired
  • get_version - Used to remotely retrieve the latest version information for a product

Each of the methods below works in the same way. The website URL that you have Easy Digital Download + Software Licensing installed on will act as the API endpoint. All requests to the API are done as either GET or POST requests and follow this form:

https://YOURSITE.com/?edd_action={request type}&item_id={download ID here}&license=cc22c1ec86304b36883440e2e84cddff&url={url of the site being licensed}

The request requires three parameters and has one optional parameter:

  • edd_action - This is the type of request (see below)
  • item_id - Use the Download ID of your download product. This is more accurate than using item_name (see below).
  • license - This is the license key you are performing an action for
  • url - (optional) This is the site URL that the API request is coming from

Instead of item_id you can also use item_name, which is the name of the download instead of the ID. Passing item_id is preferred, as that's less likely to change.

URL Tip Desktop Software

The url parameter is not limited to URLs. For example desktop software could use the url parameter for a System ID or any unique text.

Note for Plugins & Themes

This documentation covers how the API works. Refer to the following documents on integrating with WordPress Plugins & Themes:  
See our documentation about how to integrate automatic upgrades for your WordPress plugins.
See our documentation about how to integrate automatic upgrades for your WordPress themes.

Activate a License Key

To activate a license remotely, the URL you will use is:

https://YOURSITE.com/?edd_action=activate_license&item_id=8&license=cc22c1ec86304b36883440e2e84cddff&url=http://licensedsite.com

The item_id parameter (item_id=8) will be replaced with the actual ID of your product. You can find this in your dashboard beside the product: 


Note: If using item_name instead of item_id, enter the title of the product in Easy Digital Downloads exactly. Using item_id is preferred.

The license parameter is set to the license key you wish to activate.

The response for this request will be a JSON object. If the license has been successfully activated, the response will be:

{
    "success": true,
    "license": "valid",
    "item_id": false (or Item ID if passed)
    "item_name": "EDD Product Name",
    "license_limit": 0,
    "site_count": 2,
    "expires": "2020-06-30 23:59:59",
    "activations_left": "unlimited",
    "checksum": "<MD$ Checksum>",
    "payment_id": 12345,
    "customer_name": "John Doe",
    "customer_email": "john@sample.org",
    "price_id": "2"
}

If the license is invalid and failed to activate, the response will be:

{
    "success": false,
    "license": "invalid",
    "item_id": false (or Item ID if passed)
    "item_name": "EDD Product Name",
    "error": "expired",
    "expires": "2020-04-28 23:59:59",
    "license_limit": 0,
    "site_count": 1,
    "activations_left": "unlimited",
    "checksum": "<MD5 Checksum>",
    "payment_id": 12345,
    "customer_name": "John Doe",
    "customer_email": "john@sample.com",
    "price_id": "2" <optional>
}

Possible errors:

"missing" - License doesn't exist
"missing_url" - URL not provided
"license_not_activable" - Attempting to activate a bundle's parent license
"disabled" - License key revoked
"no_activations_left" - No activations left
"expired" - License has expired
"key_mismatch" - License is not valid for this product
"invalid_item_id" - Invalid Item ID
"item_name_mismatch" - License is not valid for this product

Check if a License is Valid / Active

Checking if a license is valid and not expired is very similar to activating. This request is usually done if you need to confirm that a license is still valid after it has been activated. Licenses expire after one year (by default), so this is what you will use to check if the license has expired.

To check a license remotely, the URL you will use is:

https://YOURSITE.com/?edd_action=check_license&item_id=8&license=cc22c1ec86304b36883440e2e84cddff&url=http://licensedsite.com

The item_id parameter (item_id=8) will be replaced with the actual ID of your product. You can find this in your dashboard beside the product: 

Note: If using  item_name instead of item_id, enter the title of the product in Easy Digital Downloads exactly. Using item_id is more accurate.

The license parameter is set to the license key you wish to check.

The response for this request will be a JSON object. If the license is active and still valid, the response will be:

{
    "success": true,
    "license": "valid",
    "item_id": false, (or Item ID if passed)
    "item_name": "EDD Product Name",
    "checksum": "<MD5 Checksum>",
    "expires": "2020-06-30 23:59:59",
    "payment_id": 12345,
    "customer_name": "John Doe",
    "customer_email": "john@example.org",
    "license_limit": 0,
    "site_count": 2,
    "activations_left": "unlimited",
    "price_id": "2"
}

If the license is invalid the response will be:

{
    "success": false,
    "license": "invalid",
    "item_id": false, (or Item ID if passed)
    "item_name": "EDD Product Name",
    "expires": "2014-10-23 00:00:00",
    "license_limit": 0,
    "site_count": 1,
    "activations_left": "unlimited",
    "checksum": <MD5 Checksum>,
    "payment_id": 54224,
    "customer_name": "John Doe",
    "customer_email": "john@sample.com",
    "price_id": "2" <optional>
}

Possible license statuses:

"disabled" - License key revoked
"expired" - License has expired
"key_mismatch" - License is not valid for this product
"invalid_item_id" - Invalid Item ID
"item_name_mismatch" - License is not valid for this product

Getting version information

Retrieving the version information allows you to remotely retrieve data about the latest version number, including changelogs and download links for update files.

To get version information for a license key:

https://YOURSITE.com/?edd_action=get_version&item_id=8&license=cc22c1ec86304b36883440e2e84cddff&url=http://licensedsite.com

The item_id parameter (item_id=8) will be replaced with the actual ID of your product. You can find this in your dashboard beside the product: 

Notes regarding the request: 

  • If using  item_name instead of item_id, enter the title of the product in Easy Digital Downloads exactly. Using item_id is more accurate.
  • The license and url parameters are optional. If they are omitted, the latest version information will be retrieved but no download link will be included.
  • As of Software Licensing 3.8, you can include platform versions in the request. If the platform version does not meet the minimum requirements set for the product in Easy Digital Downloads, the new_version in the response will be false instead of the new version number. php_version and wp_version are supported by default.

The response will be a JSON object that looks something like this:

{
  "new_version": "2.0",
  "stable_version": "2.0",
  "name": "Restrict Content Pro",
  "slug": "restrict-content-pro",
  "url": "https://edd.com/downloads/restrict-content-pro/?changelog=1",
  "last_updated": "2017-01-03 11:59:46",
  "homepage": "https://edd.com/downloads/restrict-content-pro/",
  "package": "",
  "download_link": "",
  "sections": "a:2:{s:11:\"description\";s:793:\"<p>Placerat porta in enim, urna cras, adipiscing augue dis lorem, pulvinar, natoque phasellus eu tincidunt, dictumst nunc ut dignissim turpis ac, pulvinar! Massa! Sed, enim, eu ac augue placerat scelerisque! Eu cursus, ridiculus cum nec lorem, natoque lorem dictumst amet! Nunc placerat dapibus enim dignissim, nunc mattis vel? Dolor nascetur placerat ridiculus augue massa porttitor turpis auctor, etiam et nisi pid ridiculus nisi duis ac. Turpis et non, dapibus diam! Placerat vel? Et, velit turpis mus sociis arcu, vel magna. Habitasse elementum elit cum nec est, eu, montes egestas est mattis lacus, turpis urna parturient, egestas, integer augue, penatibus natoque elit, rhoncus mid elementum, integer vut turpis. Et? Nisi pid. Nec, placerat ut tristique lorem a nunc velit nunc est.</p>\n\";s:9:\"changelog\";s:0:\"\";}",
  "banners": "a:2:{s:4:\"high\";s:0:\"\";s:3:\"low\";s:0:\"\";}"
}

Notes regarding the response:

  • If no license key is provided in the get_version request, the version information is still returned; however, the package and download values will be empty. Conversely, if a license key is provided but it does not belong to the item_id or item_name in the request, an error response will be returned with a reason as the msg value.
  • A download_link will be included if a file exists regardless of the state of the license. However the download will not work unless the license is active. This allows sites that have an expired license, to renew it, but not have to wait for the update caching to clear before getting the update.
  • The sections property is a serialized array that includes the full product description and changelog. If using ReadMe.txt parsing for WordPress plugins, it will also include additional information provided through the readme file.

If you wish to retrieve information about a beta version, append &beta=1 to your API request URL, like so:

https://YOURSITE.com/?edd_action=get_version&item_id=8&license=cc22c1ec86304b36883440e2e84cddff&url=http://licensedsite.com&beta=1

Retrieving versions for multiple products at once

As of Software Licensing 3.7.1, you now have the option of retrieving versions for multiple products in one request, using a new products argument. This argument accepts an array of items. Each item should contain the same arguments sent in a single request.

Here's an example using cURL:

curl -d edd_action=get_version -d products[0][item_id]=356 -d products[0][license]=59cc77ea94a2d867069a9d96142a35b8 -d products[0][url]="https://licensedsite.com" -d products[1][item_id]=46 -d products[1][license]=5cdd12a966c498fc6e423e261fe05303 -d products[1][url]="https://licensedsite.com" https://YOURSITE.com

And here's an example using the WordPress wp_remote_post() function:

$response = wp_remote_post( 'https://YOURSITE.com', array(
	'body' => array(
		'edd_action' => 'get_version',
		'products'   => array(
			'my-first-plugin' => array(
				'item_id' => 356,
				'license' => '59cc77ea94a2d867069a9d96142a35b8',
				'url'     => 'https://licensedsite.com'
			),
			'my-second-plugin' => array(
				'item_id' => 46,
				'license' => '5cdd12a966c498fc6e423e261fe05303',
				'url'     => 'https://licensedsite.com'
			)
		)
	)
) );

The response will be a JSON object containing results for each of the provided products. The product keys you provided in the request will be retained in the response. Here's an example:

{
  "my-first-plugin": {
    "new_version": "2.0",
    "stable_version": "2.0",
    "name": "My First Plugin",
    "slug": "my-first-plugin",
    "url": "https://edd.com/downloads/my-first-plugin/?changelog=1",
    "last_updated": "2021-01-03 11:59:46",
    "homepage": "https://edd.com/downloads/my-first-plugin/",
    "package": "",
    "download_link": "",
    "sections": "a:2:{s:11:\"description\";s:793:\"<p>Placerat porta in enim, urna cras, adipiscing augue dis lorem, pulvinar, natoque phasellus eu tincidunt, dictumst nunc ut dignissim turpis ac, pulvinar! Massa! Sed, enim, eu ac augue placerat scelerisque! Eu cursus, ridiculus cum nec lorem, natoque lorem dictumst amet! Nunc placerat dapibus enim dignissim, nunc mattis vel? Dolor nascetur placerat ridiculus augue massa porttitor turpis auctor, etiam et nisi pid ridiculus nisi duis ac. Turpis et non, dapibus diam! Placerat vel? Et, velit turpis mus sociis arcu, vel magna. Habitasse elementum elit cum nec est, eu, montes egestas est mattis lacus, turpis urna parturient, egestas, integer augue, penatibus natoque elit, rhoncus mid elementum, integer vut turpis. Et? Nisi pid. Nec, placerat ut tristique lorem a nunc velit nunc est.</p>\n\";s:9:\"changelog\";s:0:\"\";}",
    "banners": "a:2:{s:4:\"high\";s:0:\"\";s:3:\"low\";s:0:\"\";}"
  },
  "my-second-plugin": {
    "new_version": "1.3",
    "stable_version": "1.3",
    "name": "My Second Plugin",
    "slug": "my-second-plugin",
    "url": "https://edd.com/downloads/my-second-plugin/?changelog=1",
    "last_updated": "2021-03-08 11:59:46",
    "homepage": "https://edd.com/downloads/my-second-plugin/",
    "package": "",
    "download_link": "",
    "sections": "a:2:{s:11:\"description\";s:793:\"<p>Placerat porta in enim, urna cras, adipiscing augue dis lorem, pulvinar, natoque phasellus eu tincidunt, dictumst nunc ut dignissim turpis ac, pulvinar! Massa! Sed, enim, eu ac augue placerat scelerisque! Eu cursus, ridiculus cum nec lorem, natoque lorem dictumst amet! Nunc placerat dapibus enim dignissim, nunc mattis vel? Dolor nascetur placerat ridiculus augue massa porttitor turpis auctor, etiam et nisi pid ridiculus nisi duis ac. Turpis et non, dapibus diam! Placerat vel? Et, velit turpis mus sociis arcu, vel magna. Habitasse elementum elit cum nec est, eu, montes egestas est mattis lacus, turpis urna parturient, egestas, integer augue, penatibus natoque elit, rhoncus mid elementum, integer vut turpis. Et? Nisi pid. Nec, placerat ut tristique lorem a nunc velit nunc est.</p>\n\";s:9:\"changelog\";s:0:\"\";}",
    "banners": "a:2:{s:4:\"high\";s:0:\"\";s:3:\"low\";s:0:\"\";}"
  }
}

Accessing the API in other languages

Because the API uses simple HTTP POST requests, it can be accessed in just about any language. Here are some examples.

Creating Custom Formatted Keys

The default key format is a simple md5 sum. You may change that format to just about anything you want.

FAQ / Troubleshooting

How do I prevent access to my software, plugin or theme if the license is expired or disabled?

This license's status does not affect software, it merely indicate the status of the key. It's up to the developer reading that status to do something. For example, if a key is Expired the software could choose to stop working or could choose to pop-up a warning. 

One exception to this is that when EDD sees an expired or disabled key attached to a download, download links, including the get_version link, will not work. Therefore, updates will no longer work via the get_version response.

If you are having trouble getting license keys to activate in your implementation of Software Licensing, here are some tips to help resolve common issues.

Requests blocked by a security plugin

Security plugins for WordPress often have features that interfere with the license key API requests. These features tend to make the activation (and other API requests) return an unexpected response, causing the activation routine to fail.

For example, you might get a response like this from the server if you have a security plugin that is interfering:

[response] => Array
	(
		[code] => 403
		[message] => Forbidden
)

The iThemes Security plugin is known to have a setting that can cause this issue. The setting is called Filter Suspicious Query Strings in the URL

To resolve the issue, simply disable the  Filter Suspicious Query Strings in the URL setting. If you're not using iThemes Security, it will be named something different, though similar.

Requests blocked by special .htaccess rules

Some sites will add special rules to the .htaccess file in order to block certain IP addresses or add additional protection to the site.

If you have any special .htaccess rules in place and license keys are not activated, try removing the rules and then activating license keys. If the license keys activate properly now, you will need to adjust the rules to allow the licensing API routines to function.

Requests blocked by a coming soon or maintenance plugin

If you are using a coming soon or maintenance mode plugin, it's likely that license keys will not be able to be activated, since the coming soon / maintenance mode plugin will block the requests. To resolve the issue, simply deactivate the maintenance mode or coming soon plugin. If you need to leave it active, deactivate it temporarily to test the license key activation process and then reactivate the plugin.