# How to sign API

Request signatures are signed messages using an [ECDSA private signing key](https://docs.quadrata.com/integration/how-to-integrate/on-chain-wallet-screening/how-to-sign-api/generate-ecdsa-key-pair) and verified on the Quadrata API using the corresponding public signing key.

{% hint style="success" %}
Private signing keys are not known to Quadrata. You should take industry standard best practices to protect your private key.
{% endhint %}

###

### **Authentication**

You will need to authenticate by providing your Quadrata Login API Key, using HTTP Basic Authentication. This will allow the server to map your dApp's API Login Key to your public signing key.

```typescript
Authorization: Basic {base64(API_KEY)}
```

{% hint style="info" %}
This is the same API key you use to get an access token for the [onboarding flow.](https://docs.quadrata.com/integration/how-to-integrate/onboard-users/individual-passport-onboarding/2.-api-authentication)
{% endhint %}

### **Signing Message Format**

When verifying a request signature, the Quadrata API will attempt to create the signing message using the HTTP request and verify it with your public signing key. Since the API needs to generate a signature, you need to follow a specific generation strategy.

Included in the signing message:

1. The HTTP request method (uppercase)
2. The absolute request path
3. The query string, if one is used in the request
4. The HTTP Date header
5. A one time use nonce, if provided

{% hint style="info" %}
It is suggested to use a nonce to ensure signatures are always unique.
{% endhint %}

The signature has a short lifetime of 15 seconds. This is known from the HTTP Date header, which must be present in the signing message.

### **Signing Message Rules**

* Each part of the signing message should be joined using a new line.
* The path is always the absolute path, so it must begin with a `/`
* If the query string is not included in the request, it should be omitted completely. If it is included in the request, it should not contain the question mark `?` in the signing message.
* The signature needs to be base64-url encoded.
* If a nonce is used, it should be appended to the signature, delimited with a period `.` and also base64-url encoded.

###

### **Signing Message Example**

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

```javascript
const sigParts = [
    method.toUpperCase(),
    path,
    queryString,
    date,
    nonce
];

const signingMessageStr = sigParts
    .filter(str => str && str.length !== 0)
    .join('\n');

const signature = await signMessage(privateKey, signingMessageStr);

let signatureHeader = base64UrlEncode(signature);
if (nonce && nonce.length !== 0) {
    signatureHeader += '.' + base64UrlEncode(nonce);
}
```

{% endtab %}

{% tab title="Python" %}

```python
signature_str = '\n'.join(
    list(
        filter(
            lambda s: s and len(s) > 0,
            [
                method.upper(),
                path,
                query_string if query_string else None,
                date,
                nonce if nonce else None,
            ],
        )
    )
)

signature = sign_message(private_key, signature_str)

signature_header = base64_url_encode(signature)
if nonce is not None:
    signature_header += '.' + base64_url_encode(nonce)
```

{% endtab %}
{% endtabs %}
