> For the complete documentation index, see [llms.txt](https://document.vidau.ai/vidauai-api/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://document.vidau.ai/vidauai-api/getting-started/quickstart/authentication.md).

# Authentication

In order to use our API, you need to get your <mark style="background-color:purple;">x-auth-key</mark> and <mark style="background-color:purple;">x-client-id</mark> first.

## How to get x-client-id and x-auth-key

You can access[ API Keys](https://www.vidau.ai/site/apiKeys) to copy <mark style="background-color:purple;">x-client-id</mark> and <mark style="background-color:purple;">x-auth-key</mark>.

<figure><img src="/files/TRtOmikSroEaAOMRjQW8" alt=""><figcaption></figcaption></figure>

Do not show your <mark style="background-color:purple;">x-auth-key</mark> to anyone else. If someone gains the access ot your <mark style="background-color:purple;">x-auth-key</mark>, they can use your account as if they had your password. You can click on the Reset button to get a new one and invalidate the old one for security reasons.

## Authentication

Generate a signature based on <mark style="background-color:purple;">HMAC-SHA256</mark> algorithm through the <mark style="background-color:purple;">x-auth-key</mark> and <mark style="background-color:purple;">x-client-id</mark> to ensure the integrity and security of the request. The request <mark style="background-color:purple;">body</mark> and a <mark style="background-color:purple;">timestamp</mark> can be signed to prevent replay attacks.

### Example signature instance.

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

```java
public class ApiClient {

    public static void main(String[] args) {
        String appId = "your_app_id";
        String apiKey = "your_api_key";
        BaseReq params = new BaseReq();
        params.setXXX("your_data");
        long timestamp = System.currentTimeMillis();
        String jsonString = JsonSorterUtils.objectToJsonSorted(params);
        String signature = SignatureUtil.generateSignature(appId, apiKey, jsonString, timestamp);
        System.out.println("signature: " + signature);
    }
}
```

{% endtab %}

{% tab title="Python" %}

```python
timestamp = int(time.time() * 1000)

if __name__ == "__main__":
    class GenerateVideoReq:
        def __init__(self):
            self.webhook_url = "XXXXXX"
            self.params = {
                "voice_id": "XXXX",
                "avatar_id": XX,
                "text": "XXXX rain social services and economic growth.",
                "language": "English"
            }


    client_id = "your_app_id";
    auth_key = "your_api_key";
    req = GenerateVideoReq()
    data = JsonSorter.object_to_json_sorted(req);
    signature = generate_signature(client_id, auth_key, data, timestamp)
```

{% endtab %}
{% endtabs %}

{% hint style="danger" %}
Clear body data without extra Spaces
{% endhint %}

### Example signature method.

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

```java
public String generateSignature(String clientId, String authKey, String data, long timestamp) {
        String message = clientId + data + timestamp;
        Mac mac = null;
        try {
            mac = Mac.getInstance("HmacSHA256");
        } catch (NoSuchAlgorithmException e) {
            throw new SignatureException("HmacSHA256 is not supported");
        }
        SecretKeySpec secretKeySpec = new SecretKeySpec(authKey.getBytes(), "HmacSHA256");
        try {
            mac.init(secretKeySpec);
        } catch (InvalidKeyException e) {
            throw new SignatureException("Invalid key");
        }
        byte[] hash = mac.doFinal(message.getBytes());
        return Base64.getEncoder().encodeToString(hash);
}
```

{% endtab %}

{% tab title="Python" %}

```python
def generate_signature(client_id, auth_key, data, timestamp):
    message = f"{client_id}{data}{timestamp}"
    mac = hmac.new(auth_key.encode('utf-8'), message.encode('utf-8'), hashlib.sha256)
    signature = base64.b64encode(mac.digest()).decode('utf-8')
    return signature
```

{% endtab %}
{% endtabs %}

## Example data to be sorted by field

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

```java
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.TypeReference;

import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

public class JsonSorterUtils {

    /**
     * Converts the object into a sorted, compact JSON string。
     *
     * @param obj The object to be converted
     * @return A compact sorted JSON string
     */
    public static String objectToJsonSorted(Object obj) {
        Map<String, Object> map = JSON.parseObject(JSON.toJSONString(obj), new TypeReference<Map<String, Object>>() {});
        return JSON.toJSONString(sortMap(map));
    }

    /**
     * Sort the Map and recursively sort the Jsonobjects in it
     *
     * @param map Map that needs to be sorted
     * @return The sorted Map
     */
    private static Map<String, Object> sortMap(Map<String, Object> map) {
        if (map == null) return null;

        // Sort the external fields using TreeMap
        SortedMap<String, Object> sortedMap = new TreeMap<>(map);

        // Iterate through the Map and sort each JSONObject recursively
        for (Map.Entry<String, Object> entry : sortedMap.entrySet()) {
            if (entry.getValue() instanceof JSONObject) {
                // If it is JSONObject, it is converted to Map before sorting
                Map<String, Object> nestedMap =
                        JSON.parseObject(entry.getValue().toString(), new TypeReference<Map<String, Object>>() {});
                entry.setValue(sortMap(nestedMap));
            } else if (entry.getValue() instanceof Map) {
                // If it is a Map, it is sorted recursively
                entry.setValue(sortMap((Map<String, Object>) entry.getValue()));
            }
        }

        return sortedMap;
    }
}
```

{% endtab %}

{% tab title="Python" %}

```python
import json

class JsonSorter:
    @staticmethod
    def object_to_json_sorted(obj):
        obj_dict = JsonSorter._convert_to_dict(obj)
        sorted_dict = JsonSorter._sort_dict(obj_dict)
        return json.dumps(sorted_dict, separators=(',', ':'))

    @staticmethod
    def _convert_to_dict(obj):
        if isinstance(obj, dict):
            return obj
        elif hasattr(obj, '__dict__'):
            return obj.__dict__
        elif isinstance(obj, str):
            return json.loads(obj)
        else:
            raise ValueError("Unsupported type")

    @staticmethod
    def _sort_dict(d):
        sorted_items = sorted(d.items())
        sorted_dict = {}
        for key, value in sorted_items:
            if isinstance(value, dict):
                sorted_dict[key] = JsonSorter._sort_dict(value)
            else:
                sorted_dict[key] = value
        return sorted_dict
```

{% endtab %}
{% endtabs %}

### Example request

replace you auth-key with your actual API ID and API Key.

```sh
curl --request POST \
  --url https://vidau-app.superads.cn/openapi/ \
  --header 'Content-Type: application/json' \
  --header 'Authorization: signatureXXXXX' \
  --header 'timestamp: 1723515690000' \
  --header 'x-auth-key: you-auth-key' \
  --data '{
  "url": "https://vidau-app.superads.cn"
}'
```
