# 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"
}'
```


---

# Agent Instructions: 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://document.vidau.ai/vidauai-api/getting-started/quickstart/authentication.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.
