Skip to main content
Easy Digital Downloads Documentation
Documentation, Reference Materials, and Tutorials for Easy Digital Downloads

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. This API can be implemented with most software, not just WordPress Plugins and Themes.

In This Article

Available API Requests & Parameters
WordPress Plugin & Theme Intregration
Activate a License Key
Check if a License is Valid / Active
Getting version information
Retrieving versions for multiple products at once
API examples in other languages
FAQ / Troubleshooting


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.
    • 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. If the item_name changes, your software need to be update and past referencing the old name will no longer work.
  • 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

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.

License Keys:

  • The license key API only supports the following characters [a-z, A-Z, 0-9, -, _].
  • License keys can have a maximum length of 256 characters.

WordPress Plugins & Theme Intrigration:
Refer to the following documents on integrating Software Licensing API 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:

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": "<md5 checksum>",
    "payment_id": 12345,
    "customer_name": "John Doe",
    "customer_email": "[email protected]",
    "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": "[email protected]",
    "price_id": "2" 
  } 
  

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
"site_inactive" - Site is not active for this license
"invalid" - License key does not match
"valid" - License is valid

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:

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": "",
    "expires": "2020-06-30 23:59:59",
    "payment_id": 12345,
    "customer_name": "John Doe",
    "customer_email": "[email protected]",
    "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": "checksum",
    "payment_id": 54224,
    "customer_name": "John Doe",
    "customer_email": "[email protected]",
    "price_id": "2"
}

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

Retrieve versions for multiple products in one request, using the 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.

FAQ / Troubleshooting

Can I create Custom Formatted Keys?

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

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 the software, it merely indicates the status of the key. It’s up to the developer to read 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 the 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.