> For the complete documentation index, see [llms.txt](https://docs.licensespring.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.licensespring.com/license-api/license-api-authorization/request-signature.md).

# Request Signature

### Overview

Requests sent to the server have to be digitally signed for purposes of authentication. The signature uses the Date header and signing algorithm used in [**License API Authorization**](/license-api/license-api-authorization.md).

### Signature Structure

The **signature** in the **Authorization** header is a **Base64-encoded HMAC-hashed** value of the signing string, which is composed of:

{% stepper %}
{% step %}

### Constant string

A constant string: `licenseSpring`
{% endstep %}

{% step %}

### Newline

A newline character `\n`
{% endstep %}

{% step %}

### Date header

The value of the Date header being sent in the request (see [**License API Authorization**](/license-api/license-api-authorization.md) for more details). This is a date string in [**RFC7231**](https://datatracker.ietf.org/doc/html/rfc7231#section-7.1.1.1) format
{% endstep %}
{% endstepper %}

This signing string is then hashed with the customer's key (shared key) using the algorithm provided in the Authorization header (e.g. **HMAC-SHA256**). The resulting hash is then encoded in **Base64**.

{% hint style="info" %}
Make sure the encoded string has no extra whitespace on any line, otherwise the base64 encoded value will be incorrect.
{% endhint %}

### Example of Signature Generation

The following is an example of how to generate a signature. First, let's assume the following values:

* Your company's **shared key** is `kw4qSnpSwXzgiv5yxYpZZmFEd9QAeiKTQ6OuyMja`
* The Date header you set in the request is `Tue, 07 Jun 2011 20:51:35 GMT`
* We'll use the default hashing algorithm, HMAC-SHA256

Now we can generate the signature:

Create the signing string:

```
licenseSpring
date: Tue, 07 Jun 2011 20:51:35 GMT
```

Hash the signing string using HMAC-SHA256

Encode the hashed value with Base64: `UDysfR6MndUZReo07Y9r+vErn8vSxrnQ5ulit18iJ/Q=`

The resulting string is then inserted into the **Authorization** header as the "signature" parameter:

```
algorithm="hmac-sha256", headers="date", signature="UDysfR6MndUZReo07Y9r+vErn8vSxrnQ5ulit18iJ/Q=", apikey="_company_api_key_here_"
```

### Sample Code

Generating a **signature**

{% tabs %}
{% tab title="JavaScript" %}

```javascript
const crypto = require('node:crypto'),
    shared_key = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
    signing_string = 'licenseSpring\ndate: Tue, 07 Jun 2011 20:51:35 GMT';

let signature = crypto.createHmac('sha256', shared_key).update(signing_string).digest('base64');

console.log(signature);
// UDysfR6MndUZReo07Y9r+vErn8vSxrnQ5ulit18iJ/Q=
```

{% endtab %}

{% tab title="Python" %}

```python
import base64
import hashlib
import hmac
import time
from wsgiref.handlers import format_date_time

# Can be found in `Account Settings` -> `Settings` -> `Keys`
shared_key = '_your_shared_key_goes_here_'

def sign(secret_key, datestamp):
    msg = 'licenseSpring\ndate: %s' % datestamp
    hashed = hmac.new(bytes(secret_key, 'utf-8'), msg.encode('utf-8'), hashlib.sha256).digest()
    return base64.b64encode(hashed).decode()

# Generate headers
date_header = format_date_time(time.time())

signing_key = sign(shared_key, date_header)
```

{% endtab %}
{% endtabs %}

Generating full HTTP request headers with SDK Demo keys

{% tabs %}
{% tab title="JavaScript" %}

```javascript
const fetch = require('node-fetch');

const sharedKey = 'XXXXXXXXX-XXXXX-XXXXXXXXXXXXX_XXXXXX_XXXXXX',
      apiKey = 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX',
      productCode = "XX",
      baseURL = 'https://api.licensespring.com/api/v4/webhook';

function GenerateHeaders(){
    const signingDate = (new Date()).toUTCString(),
          signingString = `licenseSpring\ndate: ${signingDate}`;

    const signature = crypto.createHmac('sha256', sharedKey).update(signingString).digest('base64');

    return {
            'Content-Type': 'application/json',
            'Date': signingDate,
            'Authorization' : `algorithm="hmac-sha256",headers="date",signature="${signature}",apikey="${apiKey}"`,
        };
}
```

{% endtab %}

{% tab title="Python" %}

```python
import base64
import hashlib
import hmac
import time
from wsgiref.handlers import format_date_time

# Can be found in `Account Settings` -> `Settings` -> `Keys`
shared_key = '_your_shared_key_goes_here_'
uuid = '_your_uuid_key_goes_here_'

def sign(secret_key, datestamp):
    msg = 'licenseSpring\ndate: %s' % datestamp
    hashed = hmac.new(bytes(secret_key, 'utf-8'), msg.encode('utf-8'), hashlib.sha256).digest()
    return base64.b64encode(hashed).decode()

# Generating headers
date_header = format_date_time(time.time())

signing_key = sign(shared_key, date_header)

auth_header = ','.join([
    'algorithm="hmac-sha256"',
    'headers="date"',
    'signature="%s"' % signing_key,
    'apiKey="%s"' % uuid
])

headers = {
  'Date': date_header,
  'Authorization': auth_header
}
```

{% endtab %}
{% endtabs %}

Full sample code for checking a license key with SDK Demo keys

{% tabs %}
{% tab title="JavaScript" %}

```javascript
const fetch = require('node-fetch');

const sharedKey = 'XXXXXXXXX-XXXXX-XXXXXXXXXXXXX_XXXXXX_XXXXXX',
      apiKey = 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX',
      productCode = "XX",
      baseURL = 'https://api.licensespring.com/api/v4';

function GenerateHeaders(){
    const signingDate = (new Date()).toUTCString(),
          signingString = `licenseSpring\ndate: ${signingDate}`;

    const signature = crypto.createHmac('sha256', sharedKey).update(signingString).digest('base64');

    return {
            'Content-Type': 'application/json',
            'Date': signingDate,
            'Authorization' : `algorithm="hmac-sha256",headers="date",signature="${signature}",apikey="${apiKey}"`,
        };
}

const checkLicense = async (hwid, licenseKey) => {
    const headers = GenerateHeaders()

    const response = await fetch(baseURL + '/check_license' + `?product=${productCode}&hardware_id=${hwid}&license_key=${licenseKey}`, {
        method: 'GET',
        headers: headers
    })
    console.log("/license response", await response.json());
}

checkLicense('d32q3ed3rq3rxq2r3q23q23q23', '1111-2222-3333-4444');
```

{% endtab %}

{% tab title="Python" %}

```python
import base64
import hashlib
import hmac
import time
from wsgiref.handlers import format_date_time

import requests

API_URL = 'https://api.licensespring.com'

# Can be found in `Account Settings` -> `Settings` -> `Keys`
shared_key = '_your_shared_key_goes_here_'
uuid = '_your_uuid_key_goes_here_'

def sign(secret_key, datestamp):
    msg = 'licenseSpring\ndate: %s' % datestamp
    hashed = hmac.new(bytes(secret_key, 'utf-8'), msg.encode('utf-8'), hashlib.sha256).digest()
    return base64.b64encode(hashed).decode()

# Generate headers
date_header = format_date_time(time.time())

signing_key = sign(shared_key, date_header)

auth_header = ','.join([
    'algorithm="hmac-sha256"',
    'headers="date"',
    'signature="%s"' % signing_key,
    'apiKey="%s"' % uuid
])

# Send request
product_short_code = '_your_product_short_code_goes_here_'
hardware_id = '_your_hardware_id_goes_here_'
license_key = '_your_license_key_goes_here_'

response = requests.get(
    url='{}{}'.format(API_URL, '/api/v4/check_license/'),
    params={'product': product_short_code, 'hardware_id': hardware_id, 'license_key': license_key},
    headers={
        'Date': date_header,
        'Authorization': auth_header,
        'Content-Type': 'application/json'
    }
)

print(response.json())
```

{% endtab %}
{% endtabs %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.licensespring.com/license-api/license-api-authorization/request-signature.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
