# Software Licensing API

The API included with the [Software Licensing extension](https://easydigitaldownloads.com/extension/software-licensing/) 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 &amp; Parameters](#api-requests-parameters &quot;Available API Requests &amp; Parameters
&quot;)[WordPress Plugin &amp; Theme Intregration](#wordpress-intregration &quot;WordPress Plugin &amp; Theme Intregration
&quot;)[Activate a License Key](#activate_license &quot;Activate a License Key
&quot;)[Check if a License is Valid / Active](#check_license)[Getting version information](#get_version &quot;Getting version information
&quot;)[Retrieving versions for multiple products at once](#versions-for-multiple-products &quot;Retrieving versions for multiple products at once&quot;)
[API examples in other languages](#examples &quot;Accessing the API in other languages&quot;)
[FAQ / Troubleshooting](#faqs &quot;FAQ / Troubleshooting&quot;)

---

**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}&amp;item_id={download ID here}&amp;license=cc22c1ec86304b36883440e2e84cddff&amp;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&#039;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 &amp; Theme Intrigration:** Refer to the following documents on integrating Software Licensing API with WordPress Plugins &amp; Themes: 
[See our documentation about how to integrate automatic upgrades for your WordPress plugins](https://easydigitaldownloads.com/docs/software-licensing-updater-implementation-for-wordpress-plugins/).
[See our documentation about how to integrate automatic upgrades for your WordPress themes](https://easydigitaldownloads.com/docs/software-licensing-updater-implementation-for-wordpress-themes/)

### Activate a License Key

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

```
https://YOURSITE.com/?edd_action=activate_license&amp;item_id=8&amp;license=cc22c1ec86304b36883440e2e84cddff&amp;url=https://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:

![](https://easydigitaldownloads.com/wp-content/uploads/2022/07/6184cd1d4b999.jpg)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:

```
{
    &quot;success&quot;: true,
    &quot;license&quot;: &quot;valid&quot;,
    &quot;item_id&quot;: false (or Item ID if passed)
    &quot;item_name&quot;: &quot;EDD Product Name&quot;,
    &quot;license_limit&quot;: 0,
    &quot;site_count&quot;: 2,
    &quot;expires&quot;: &quot;2020-06-30 23:59:59&quot;,
    &quot;activations_left&quot;: &quot;unlimited&quot;,
    &quot;checksum&quot;: &quot;&lt;md5 checksum&gt;&quot;,
    &quot;payment_id&quot;: 12345,
    &quot;customer_name&quot;: &quot;John Doe&quot;,
    &quot;customer_email&quot;: &quot;john@sample.org&quot;,
    &quot;price_id&quot;: &quot;2&quot;
}
```

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

```
{
    &quot;success&quot;: false,
    &quot;license&quot;: &quot;invalid&quot;,
    &quot;item_id&quot;: false (or Item ID if passed)
    &quot;item_name&quot;: &quot;EDD Product Name&quot;,
    &quot;error&quot;: &quot;expired&quot;,
    &quot;expires&quot;: &quot;2020-04-28 23:59:59&quot;,
    &quot;license_limit&quot;: 0,
    &quot;site_count&quot;: 1,
    &quot;activations_left&quot;: &quot;unlimited&quot;,
    &quot;checksum&quot;: &quot;&lt;md5 checksum&gt;&quot;,
    &quot;payment_id&quot;: 12345,
    &quot;customer_name&quot;: &quot;John Doe&quot;,
    &quot;customer_email&quot;: &quot;john@sample.com&quot;,
    &quot;price_id&quot;: &quot;2&quot; 
  } 
  
```

Possible errors:

```
&quot;missing&quot; - License doesn&#039;t exist
&quot;missing_url&quot; - URL not provided
&quot;license_not_activable&quot; - Attempting to activate a bundle&#039;s parent license
&quot;disabled&quot; - License key revoked
&quot;no_activations_left&quot; - No activations left
&quot;expired&quot; - License has expired
&quot;key_mismatch&quot; - License is not valid for this product
&quot;invalid_item_id&quot; - Invalid Item ID
&quot;item_name_mismatch&quot; - License is not valid for this product
&quot;site_inactive&quot; - Site is not active for this license
&quot;invalid&quot; - License key does not match
&quot;valid&quot; - 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&amp;item_id=8&amp;license=cc22c1ec86304b36883440e2e84cddff&amp;url=https://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:

![](https://easydigitaldownloads.com/wp-content/uploads/2022/07/6184cd1d4b999.jpg)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:

```
{
    &quot;success&quot;: true,
    &quot;license&quot;: &quot;valid&quot;,
    &quot;item_id&quot;: false, (or Item ID if passed)
    &quot;item_name&quot;: &quot;EDD Product Name&quot;,
    &quot;checksum&quot;: &quot;&lt;md5 checksum=&quot;&quot;&gt;&quot;,
    &quot;expires&quot;: &quot;2020-06-30 23:59:59&quot;,
    &quot;payment_id&quot;: 12345,
    &quot;customer_name&quot;: &quot;John Doe&quot;,
    &quot;customer_email&quot;: &quot;john@example.org&quot;,
    &quot;license_limit&quot;: 0,
    &quot;site_count&quot;: 2,
    &quot;activations_left&quot;: &quot;unlimited&quot;,
    &quot;price_id&quot;: &quot;2&quot;
}
&lt;/md5&gt;
```

If the license is invalid the response will be:

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

Possible license statuses:

```
&quot;disabled&quot; - License key revoked
&quot;expired&quot; - License has expired
&quot;key_mismatch&quot; - License is not valid for this product
&quot;invalid_item_id&quot; - Invalid Item ID
&quot;item_name_mismatch&quot; - 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&amp;item_id=8&amp;license=cc22c1ec86304b36883440e2e84cddff&amp;url=https://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:

![](https://easydigitaldownloads.com/wp-content/uploads/2022/07/6184cd1d4b999.jpg)#### 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:

```
{
  &quot;new_version&quot;: &quot;2.0&quot;,
  &quot;stable_version&quot;: &quot;2.0&quot;,
  &quot;name&quot;: &quot;Restrict Content Pro&quot;,
  &quot;slug&quot;: &quot;restrict-content-pro&quot;,
  &quot;url&quot;: &quot;https://edd.com/downloads/restrict-content-pro/?changelog=1&quot;,
  &quot;last_updated&quot;: &quot;2017-01-03 11:59:46&quot;,
  &quot;homepage&quot;: &quot;https://edd.com/downloads/restrict-content-pro/&quot;,
  &quot;package&quot;: &quot;&quot;,
  &quot;download_link&quot;: &quot;&quot;,
  &quot;sections&quot;: &quot;a:2:{s:11:&quot;description&quot;;s:793:&quot;&lt;p&gt;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.&lt;/p&gt;n&quot;;s:9:&quot;changelog&quot;;s:0:&quot;&quot;;}&quot;,
  &quot;banners&quot;: &quot;a:2:{s:4:&quot;high&quot;;s:0:&quot;&quot;;s:3:&quot;low&quot;;s:0:&quot;&quot;;}&quot;
}
```

#### 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](https://easydigitaldownloads.com/docs/software-licensing-parsing-readme-txt-files-in-wordpress-plugins/), it will also include additional information provided through the readme file.

If you wish to retrieve information about a [beta version](https://easydigitaldownloads.com/docs/software-licensing-releasing-beta-versions/), append *&amp;beta=1* to your API request URL, like so:

```
https://YOURSITE.com/?edd_action=get_version&amp;item_id=8&amp;license=cc22c1ec86304b36883440e2e84cddff&amp;url=https://licensedsite.com&amp;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&#039;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]=&quot;https://licensedsite.com&quot; -d products[1][item_id]=46 -d products[1][license]=5cdd12a966c498fc6e423e261fe05303 -d products[1][url]=&quot;https://licensedsite.com&quot; https://YOURSITE.com
```

And here&#039;s an example using the WordPress
`wp_remote_post()` function:

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

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&#039;s an example:

```
{
  &quot;my-first-plugin&quot;: {
    &quot;new_version&quot;: &quot;2.0&quot;,
    &quot;stable_version&quot;: &quot;2.0&quot;,
    &quot;name&quot;: &quot;My First Plugin&quot;,
    &quot;slug&quot;: &quot;my-first-plugin&quot;,
    &quot;url&quot;: &quot;https://edd.com/downloads/my-first-plugin/?changelog=1&quot;,
    &quot;last_updated&quot;: &quot;2021-01-03 11:59:46&quot;,
    &quot;homepage&quot;: &quot;https://edd.com/downloads/my-first-plugin/&quot;,
    &quot;package&quot;: &quot;&quot;,
    &quot;download_link&quot;: &quot;&quot;,
    &quot;sections&quot;: &quot;a:2:{s:11:&quot;description&quot;;s:793:&quot;&lt;p&gt;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.&lt;/p&gt;n&quot;;s:9:&quot;changelog&quot;;s:0:&quot;&quot;;}&quot;,
    &quot;banners&quot;: &quot;a:2:{s:4:&quot;high&quot;;s:0:&quot;&quot;;s:3:&quot;low&quot;;s:0:&quot;&quot;;}&quot;
  },
  &quot;my-second-plugin&quot;: {
    &quot;new_version&quot;: &quot;1.3&quot;,
    &quot;stable_version&quot;: &quot;1.3&quot;,
    &quot;name&quot;: &quot;My Second Plugin&quot;,
    &quot;slug&quot;: &quot;my-second-plugin&quot;,
    &quot;url&quot;: &quot;https://edd.com/downloads/my-second-plugin/?changelog=1&quot;,
    &quot;last_updated&quot;: &quot;2021-03-08 11:59:46&quot;,
    &quot;homepage&quot;: &quot;https://edd.com/downloads/my-second-plugin/&quot;,
    &quot;package&quot;: &quot;&quot;,
    &quot;download_link&quot;: &quot;&quot;,
    &quot;sections&quot;: &quot;a:2:{s:11:&quot;description&quot;;s:793:&quot;&lt;p&gt;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.&lt;/p&gt;n&quot;;s:9:&quot;changelog&quot;;s:0:&quot;&quot;;}&quot;,
    &quot;banners&quot;: &quot;a:2:{s:4:&quot;high&quot;;s:0:&quot;&quot;;s:3:&quot;low&quot;;s:0:&quot;&quot;;}&quot;
  }
}
```

### 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.

- [Software Licensing API - Example using cURL](https://easydigitaldownloads.com/docs/software-licensing-api-example-using-curl/)
- [Software Licensing API - Example using Perl](https://easydigitaldownloads.com/docs/software-licensing-api-example-using-perl/)
- [Software Licensing API - Example using Python](https://easydigitaldownloads.com/docs/software-licensing-api-example-using-python/)
- [Software Licensing API - Example using Ruby](https://easydigitaldownloads.com/docs/software-licensing-api-example-using-ruby/)
- [Software Licensing API - Example using C#](https://easydigitaldownloads.com/docs/software-licensing-api-example-using-c/)
- [Software Licensing API - Example using JavaScript](https://easydigitaldownloads.com/docs/software-licensing-api-example-using-javascript/)
- [Software Licensing API - Example using jQuery](https://easydigitaldownloads.com/docs/software-licensing-api-example-using-jquery/)

### 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](https://easydigitaldownloads.com/docs/software-licensing-common-issues-and-faqs/).

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

This license&#039;s status does not affect the software, it merely indicates the status of the key. It&#039;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](https://easydigitaldownloads.com/downloads/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] =&gt; Array
	(
		[code] =&gt; 403
		[message] =&gt; 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&#039;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&#039;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.