# AI Model Source: https://docs.akool.com/ai-tools-suite/aimodel Get available AI models for different generation tasks including text-to-image, image-to-video, and more. Use this API to dynamically retrieve available AI models and their configurations for your application. ## Get AI Model List ``` GET https://openapi.akool.com/api/open/v4/aigModel/list ``` **Request Headers** | **Parameter** | **Value** | **Description** | | ------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | x-api-key | API Key | Your API Key used for request authorization. If both Authorization and x-api-key have values, Authorization will be used first and x-api-key will be discarded. | | Authorization | Bearer `{token}` | Your API Key used for request authorization.[Get Token](/authentication/usage#get-the-token) | **Query Parameters** | **Parameter** | **Type** | **Required** | **Description** | | ------------- | -------- | ------------ | --------------------------------------------------------------- | | types | Array | true | Array of model types to retrieve. At least one type is required | **Supported Model Types** | **Type Value** | **Description** | | -------------- | ------------------------------------------------------ | | 1501 | Image to Video - Animate static images into videos | | 1502 | Text to Video - Generate videos from text descriptions | | 2101 | Character Faceswap - Face swap for character videos | **Response Attributes** | **Parameter** | **Type** | **Description** | | ------------- | -------- | ----------------------------------------------------- | | code | Integer | Interface returns business status code (1000:success) | | msg | String | Interface returns status information | | data | Array | Array of model configuration objects | **Model Configuration Object** | **Parameter** | **Type** | **Description** | | --------------------- | ------------ | ----------------------------------------------------- | | sort | Integer | Sort order (higher values appear first) | | group | String | Model group/category | | provider | String | Model provider (akool, seedance, minimax, vidu, etc.) | | type | Integer | Model type (matches request types) | | label | String | Display name of the model | | value | String | Model identifier to use in API calls | | description | String | Model description | | resolutionList | Array | Supported resolutions with pricing details | | isPro | Boolean | Whether this is a premium model | | generate\_audio | Boolean/null | Whether the model supports audio generation | | durationList | Array | Supported video durations in seconds | | requiresPay | Boolean | Whether a paid account is required | | supportedLastFrame | Boolean | Whether the model supports last frame specification | | supportedExtendPrompt | Boolean | Whether the model supports prompt extension | | maxImageCount | Integer | Maximum number of reference images supported | | maxCount | Integer | Maximum number of items per batch | **resolutionList Item Attributes** | **Parameter** | **Type** | **Description** | | ------------- | -------- | ---------------------------------------- | | label | String | Display label for the resolution | | value | String | Resolution value (e.g., "720p", "1080p") | | width | Integer | Video width in pixels | | height | Integer | Video height in pixels | ## Examples ### Example 1: Get Image to Video Models **Request** ```bash cURL theme={null} curl --location 'https://openapi.akool.com/api/open/v4/aigModel/list?types[]=1501' \ --header 'x-api-key: {{API Key}}' ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); Request request = new Request.Builder() .url("https://openapi.akool.com/api/open/v4/aigModel/list?types[]=1501") .method("GET", null) .addHeader("x-api-key", "{{API Key}}") .build(); Response response = client.newCall(request).execute(); ``` ```js Javascript theme={null} const myHeaders = new Headers(); myHeaders.append("x-api-key", "{{API Key}}"); const requestOptions = { method: "GET", headers: myHeaders, redirect: "follow" }; fetch("https://openapi.akool.com/api/open/v4/aigModel/list?types[]=1501", requestOptions) .then((response) => response.text()) .then((result) => console.log(result)) .catch((error) => console.error(error)); ``` ```php PHP theme={null} '{{API Key}}' ]; $request = new Request('GET', 'https://openapi.akool.com/api/open/v4/aigModel/list?types[]=1501', $headers); $res = $client->sendAsync($request)->wait(); echo $res->getBody(); ?> ``` ```python Python theme={null} import requests url = "https://openapi.akool.com/api/open/v4/aigModel/list?types[]=1501" headers = { 'x-api-key':'{{API Key}}' } response = requests.request("GET", url, headers=headers) print(response.text) ``` **Response** ```json theme={null} { "code": 1000, "msg": "OK", "data": [ { "sort": 100, "group": "akool", "provider": "akool", "type": 1501, "label": "Akool Image2Video Fast V1", "value": "AkoolImage2VideoFastV1", "description": "Fast image to video generation with Akool's AI", "resolutionList": [ { "label": "720p", "value": "720p", "width": 1280, "height": 720, "unit_credit": 5 }, { "label": "1080p", "value": "1080p", "width": 1920, "height": 1080, "unit_credit": 10 }, { "label": "4k", "value": "4k", "width": 3840, "height": 2160, "unit_credit": 20 } ], "isPro": false, "generate_audio": null, "durationList": [5, 10], "requiresPay": false, "supportedLastFrame": false, "supportedExtendPrompt": false, "maxImageCount": 1, "maxCount": 10 }, { "sort": 95, "group": "seedance", "provider": "seedance", "type": 1501, "label": "Seedance Lite Image2Video", "value": "seedance-1-0-lite-i2v-250428", "description": "Seedance Lite model for image to video generation", "resolutionList": [ { "label": "480p", "value": "480p", "width": 854, "height": 480, "unit_credit": 3 }, { "label": "720p", "value": "720p", "width": 1280, "height": 720, "unit_credit": 5 }, { "label": "1080p", "value": "1080p", "width": 1920, "height": 1080, "unit_credit": 10 } ], "isPro": false, "generate_audio": null, "durationList": [5, 10], "requiresPay": false, "supportedLastFrame": true, "supportedExtendPrompt": false, "maxImageCount": 1, "maxCount": 10 } ] } ``` ## Response Data Structure ```javascript theme={null} { code: 1000, msg: "OK", data: [ { // Model metadata sort: 100, // Higher = appears first group: "akool", // Model group provider: "akool", // Provider name type: 1501, // Model type // Display information label: "Model Name", value: "model_identifier", description: "Description", // Pricing & limits requiresPay: false, isPro: false, maxCount: 10, // Supported parameters resolutionList: [...], durationList: [5, 10], // Features supportedLastFrame: false, supportedExtendPrompt: false, maxImageCount: 1, } ] } ``` # Background Change Source: https://docs.akool.com/ai-tools-suite/background-change The resources (image, video, voice) generated by our API are valid for 7 days. Please save the relevant resources as soon as possible to prevent expiration. ### Background Change ``` POST https://openapi.akool.com/api/open/v3/content/image/bg/replace ``` **Request Headers** | **Parameter** | **Value** | **Description** | | ------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | x-api-key | API Key | Your API Key used for request authorization. If both Authorization and x-api-key have values, Authorization will be used first and x-api-key will be discarded. | | Authorization | Bearer `{token}` | Your API Key used for request authorization.[Get Token](/authentication/usage#get-the-token) | **Body Attributes** | **Parameter** | **isRequired** | **Type** | **Value** | **Description** | | ------------------------- | -------------- | -------- | ----------------------------- | --------------------------------------------------------------------------- | | color\_code | false | String | eg: #aafbe3 | background color。 Use hexadecimal to represent colors | | template\_url | false | String | | resource address of the background image | | origin\_img | true | String | | Foreground image address | | modify\_template\_size | false | String | eg:"3031x3372" | The size of the template image after expansion | | modify\_origin\_img\_size | true | String | eg: "3031x2894" | The size of the foreground image after scaling | | overlay\_origin\_x | true | int | eg: 205 | The position of the upper left corner of the foreground image in the canvas | | overlay\_origin\_y | true | int | eg: 497 | The position of the upper left corner of the foreground image in the canvas | | overlay\_template\_x | false | int | eg: 10 | The position of the upper left corner of the template image in the canvas | | overlay\_template\_y | false | int | eg: 497 | The position of the upper left corner of the template image in the canvas | | canvas\_size | true | String | eg:"3840x3840" | Canvas size | | webhookUrl | true | String | | Callback url address based on HTTP request | | removeBg | false | Boolean | true or false default false | Whether to remove the background image | In addition to using the required parameters,you can also use one or both of the color\_code or template\_url parameters(but this is not required). Once you use template\_url, you can carry three additional parameters: modify\_template\_size, overlay\_template\_x, and overlay\_template\_y. **Response Attributes** | **Parameter** | **Type** | **Value** | **Description** | | ------------- | -------- | ------------------------------ | ------------------------------------------------------------------------------------------------------------------ | | code | int | 1000 | Interface returns business status code(1000:success) | | msg | String | | Interface returns status information | | data | Object | `{ _id: "", image_status: 1 }` | \_id: Interface returns data, image\_status: the status of image: 【1:queueing, 2:processing, 3:completed,4:failed】 | **Example** **Body** You have 4 combination parameters to choose from The first combination of parameters: use template\_url ```json theme={null} { "canvas_size": "3840x3840", "template_url": "https://d3c24lvfmudc1v.cloudfront.net/public/background_change/ROne.png", "modify_template_size": "3830x3830", "overlay_template_x": 5, "overlay_template_y": 5, "origin_img": "https://drz0f01yeq1cx.cloudfront.net/1711939252580-7e40bd1a-e480-42ed-8585-3f9ffccf6bdb-5822.png", "modify_origin_img_size": "3830x2145", "overlay_origin_x": 5, "overlay_origin_y": 849 } ``` The second combination of parameters:use color\_code ```json theme={null} { "color_code": "#c9aafb", "canvas_size": "3840x3840", "origin_img": "https://drz0f01yeq1cx.cloudfront.net/1712132369637-69a946c0-b2a7-4fe6-92c8-2729b36cc13e-0183.png", "modify_origin_img_size": "3060x3824", "overlay_origin_x": 388, "overlay_origin_y": 8 } ``` The third combination of parameters: use template\_url and color\_code ```json theme={null} { "color_code": "#aafbe3", "canvas_size": "3840x3840", "template_url": "https://d3c24lvfmudc1v.cloudfront.net/public/background_change/ROne.png", "modify_template_size": "3828x3828", "overlay_template_x": 2049, "overlay_template_y": -6, "origin_img": "https://drz0f01yeq1cx.cloudfront.net/1712132369637-69a946c0-b2a7-4fe6-92c8-2729b36cc13e-0183.png", "modify_origin_img_size": "3062x3828", "overlay_origin_x": -72, "overlay_origin_y": -84 } ``` The fourth combination of parameters: ```json theme={null} { "canvas_size": "3840x3840", "origin_img": "https://drz0f01yeq1cx.cloudfront.net/1712132369637-69a946c0-b2a7-4fe6-92c8-2729b36cc13e-0183.png", "modify_origin_img_size": "3060x3824", "overlay_origin_x": 388, "overlay_origin_y": 8 } ``` **Request** ```bash cURL theme={null} curl --location 'https://openapi.akool.com/api/open/v3/content/image/bg/replace' \ --header "x-api-key: {{API Key}}" \ --header 'Content-Type: application/json' \ --data '{ "canvas_size": "3840x3840", "template_url": "https://d3c24lvfmudc1v.cloudfront.net/public/background_change/ROne.png", "modify_template_size": "3830x3830", "overlay_template_x": 5, "overlay_template_y": 5, "origin_img": "https://drz0f01yeq1cx.cloudfront.net/1711939252580-7e40bd1a-e480-42ed-8585-3f9ffccf6bdb-5822.png", "modify_origin_img_size": "3830x2145", "overlay_origin_x": 5, "overlay_origin_y": 849 } ' ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, "{\n \"canvas_size\": \"3840x3840\",\n \"template_url\": \"https://d3c24lvfmudc1v.cloudfront.net/public/background_change/ROne.png\",\n \"modify_template_size\": \"3830x3830\",\n \"overlay_template_x\": 5,\n \"overlay_template_y\": 5,\n \"origin_img\": \"https://drz0f01yeq1cx.cloudfront.net/1711939252580-7e40bd1a-e480-42ed-8585-3f9ffccf6bdb-5822.png\",\n \"modify_origin_img_size\": \"3830x2145\",\n \"overlay_origin_x\": 5,\n \"overlay_origin_y\": 849,\n}"); Request request = new Request.Builder() .url("https://contentapi.akool.com/api/v3/content/image/bg/replace") .method("POST", body) .addHeader("x-api-key", "{{API Key}}") .addHeader("content-type", "application/json") .build(); Response response = client.newCall(request).execute(); ``` ```javascript Javascript theme={null} const myHeaders = new Headers(); myHeaders.append("x-api-key", "{{API Key}}"); myHeaders.append("Content-Type", "application/json"); const raw = JSON.stringify({ "canvas_size": "3840x3840", "template_url": "https://d3c24lvfmudc1v.cloudfront.net/public/background_change/ROne.png", "modify_template_size": "3830x3830", "overlay_template_x": 5, "overlay_template_y": 5, "origin_img": "https://drz0f01yeq1cx.cloudfront.net/1711939252580-7e40bd1a-e480-42ed-8585-3f9ffccf6bdb-5822.png", "modify_origin_img_size": "3830x2145", "overlay_origin_x": 5, "overlay_origin_y": 849 }); const requestOptions = { method: "POST", headers: myHeaders, body: raw, redirect: "follow" }; fetch("https://openapi.akool.com/api/open/v3/content/image/bg/replace", requestOptions) .then((response) => response.text()) .then((result) => console.log(result)) .catch((error) => console.error(error)); ``` ```php PHP theme={null} '{{API Key}}', 'Content-Type' => 'application/json' ]; $body = '{ "canvas_size": "3840x3840", "template_url": "https://d3c24lvfmudc1v.cloudfront.net/public/background_change/ROne.png", "modify_template_size": "3830x3830", "overlay_template_x": 5, "overlay_template_y": 5, "origin_img": "https://drz0f01yeq1cx.cloudfront.net/1711939252580-7e40bd1a-e480-42ed-8585-3f9ffccf6bdb-5822.png", "modify_origin_img_size": "3830x2145", "overlay_origin_x": 5, "overlay_origin_y": 849 }'; $request = new Request('POST', 'https://openapi.akool.com/api/open/v3/content/image/bg/replace', $headers, $body); $res = $client->sendAsync($request)->wait(); echo $res->getBody(); ``` ```python Python theme={null} import requests import json url = "https://openapi.akool.com/api/open/v3/content/image/bg/replace" payload = json.dumps({ "canvas_size": "3840x3840", "template_url": "https://d3c24lvfmudc1v.cloudfront.net/public/background_change/ROne.png", "modify_template_size": "3830x3830", "overlay_template_x": 5, "overlay_template_y": 5, "origin_img": "https://drz0f01yeq1cx.cloudfront.net/1711939252580-7e40bd1a-e480-42ed-8585-3f9ffccf6bdb-5822.png", "modify_origin_img_size": "3830x2145", "overlay_origin_x": 5, "overlay_origin_y": 849 }) headers = { 'x-api-key':'{{API Key}}', 'Content-Type': 'application/json' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text) ``` **Response** ```json theme={null} { "code": 1000, "msg": "OK", "data": { "create_time": 1712133151184, "uid": 1432101, "type": 3, "faceswap_quality": 2, "image_id": "c7ed5294-6783-481e-af77-61a850cd19c7", "image_sub_status": 1, "image_status": 1, // the status of image: 【1:queueing, 2:processing,3:completed, 4:failed】 "deduction_credit": 4, "buttons": [], "used_buttons": [], "upscaled_urls": [], "error_reasons": [], "_id": "660d15b83ec46e810ca642f5", "__v": 0 } } ``` ### Get Image Result image info ``` GET https://openapi.akool.com/api/open/v3/content/image/infobymodelid?image_model_id=660d15b83ec46e810ca642f5 ``` **Request Headers** | **Parameter** | **Value** | **Description** | | ------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | x-api-key | API Key | Your API Key used for request authorization. If both Authorization and x-api-key have values, Authorization will be used first and x-api-key will be discarded. | | Authorization | Bearer `{token}` | Your API Key used for request authorization.[Get Token](/authentication/usage#get-the-token) | **Query Attributes** | **Parameter** | **Type** | **Value** | **Description** | | ---------------- | -------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | | image\_model\_id | String | | image db id:You can get it based on the `_id` field returned by [Background Replace API](/ai-tools-suite/background-change#background-change) api. | **Response Attributes** | **Parameter** | **Type** | **Value** | **Description** | | ------------- | -------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | | code | int | 1000 | Interface returns business status code(1000:success) | | msg | String | | Interface returns status information | | data | Object | `{image_status:1,_id:"",image:""}` | image\_status: the status of image: 【1:queueing, 2:processing, 3:completed, 4:failed】 image: Image result after processing \_id: Interface returns data | **Example** **Request** ```bash cURL theme={null} curl --location 'https://openapi.akool.com/api/open/v3/content/image/infobymodelid?image_model_id=660d15b83ec46e810ca642f5' \ --header "x-api-key: {{API Key}}" ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("text/plain"); RequestBody body = RequestBody.create(mediaType, ""); Request request = new Request.Builder() .url("https://openapi.akool.com/api/open/v3/content/image/infobymodelid?image_model_id=660d15b83ec46e810ca642f5") .method("GET", body) .addHeader("x-api-key", "{{API Key}}") .build(); Response response = client.newCall(request).execute(); ``` ```js Javascript theme={null} const myHeaders = new Headers(); myHeaders.append("x-api-key", "{{API Key}}"); const requestOptions = { method: "GET", headers: myHeaders, redirect: "follow" }; fetch("https://openapi.akool.com/api/open/v3/content/image/infobymodelid?image_model_id=660d15b83ec46e810ca642f5", requestOptions) .then((response) => response.text()) .then((result) => console.log(result)) .catch((error) => console.error(error)); ``` ```php PHP theme={null} '{{API Key}}' ]; $request = new Request('GET', 'https://openapi.akool.com/api/open/v3/content/image/infobymodelid?image_model_id=660d15b83ec46e810ca642f5', $headers); $res = $client->sendAsync($request)->wait(); echo $res->getBody(); ``` ```python Python theme={null} import requests url = "https://openapi.akool.com/api/open/v3/content/image/infobymodelid?image_model_id=660d15b83ec46e810ca642f5" payload = {} headers = { 'x-api-key':'{{API Key}}' } response = requests.request("GET", url, headers=headers, data=payload) print(response.text) ``` **Response** ```json theme={null} { "code": 1000, "msg": "OK", "data": { "_id": "660d15b83ec46e810ca642f5", "create_time": 1712133560525, "uid": 1486241, "type": 3, "faceswap_quality": 2, "image_id": "e23018b5-b7a9-4981-a2ff-b20559f9b2cd", "image_sub_status": 3, "image_status": 3, // the status of image:【1:queueing, 2:processing,3:completed,4:failed】 "deduction_credit": 4, "buttons": [], "used_buttons": [], "upscaled_urls": [], "error_reasons": [], "__v": 0, "external_img": "https://drz0f01yeq1cx.cloudfront.net/1712133563402-result.png", "image": "https://drz0f01yeq1cx.cloudfront.net/1712133564746-d4a80a20-9612-4f59-958b-db9dec09b320-9409.png" // Image result after processing } } ``` **Response Code Description** Please note that if the value of the response code is not equal to 1000, the request is failed or wrong | **Parameter** | **Value** | **Description** | | ------------- | --------- | --------------------------------------------------------------------- | | code | 1000 | Success | | code | 1003 | Parameter error or Parameter can not be empty | | code | 1005 | Operation is too frequent | | code | 1006 | Your quota is not enough | | code | 1007 | The number of people who can have their faces changed cannot exceed 8 | | code | 1101 | Invalid authorization or The request token has expired | | code | 1102 | Authorization cannot be empty | | code | 1200 | The account has been banned | # Character Swap API Overview Source: https://docs.akool.com/ai-tools-suite/character-swap/character-swap Comprehensive guide to the Character Swap API The resources (image, video) generated by our API are valid for 7 days. Please save the relevant resources as soon as possible to prevent expiration. ## API Endpoints ### Character Swap Operations * [Create Character Swap](/ai-tools-suite/character-swap/create) - Create animated video from character image and source video * [Get Video Info Result](/ai-tools-suite/character-swap/get-result) - Retrieve character swap video results by ID ## Getting Started ### Basic Workflow 1. **Create Character Swap Video**: * Prepare your character image URL (PNG or JPEG) * Prepare your source video URL (MP4) with the motion to apply * Optionally provide duration, resolution, mode, and prompt * Call the [Create Character Swap API](/ai-tools-suite/character-swap/create) with your resources 2. **Check Results**: * Use the [Get Video Info Result API](/ai-tools-suite/character-swap/get-result) to check the status of your video * Download the result URL when the status is "Success" (video\_status = 3) ### Response Code Description Please note that if the value of the response code is not equal to 1000, the request has failed or encountered an error. | Code | Description | | ---- | ------------------------------------------------------ | | 1000 | Success | | 1003 | Parameter error or Parameter cannot be empty | | 1008 | The content you get does not exist | | 1009 | You do not have permission to operate | | 1015 | Create video error, please try again later | | 1101 | Invalid authorization or The request token has expired | | 1102 | Authorization cannot be empty | | 1200 | The account has been banned | ## Pricing ### Character Swap | Resolution | Unit Credit (per 5 seconds) | | ---------- | --------------------------- | | 480p | 5 credits | | 720p | 10 credits | | 1080p | 15 credits | **Note:** Credits are calculated based on video duration in 5-second increments. For example, a 12-second video at 720p resolution would cost 30 credits (12 seconds ÷ 5 seconds × 10 credits). ## Video Status Codes When checking results, the `video_status` field indicates the current state: | Status | Description | | ------ | ------------------------------------------------------------------- | | 1 | In Queue - Your request is waiting to be processed | | 2 | Processing - Character swap video is currently being generated | | 3 | Success - Video completed, result URL is available | | 4 | Failed - Video generation failed, please check your input resources | ## Best Practices ### Image Requirements * **Quality**: Use high-resolution images for better results * **Face Visibility**: Ensure the character face is clearly visible and not obscured * **Lighting**: Well-lit images produce better character swap results * **Angle**: Frontal or slight angle faces work best ### Video Requirements * **Format**: MP4 format is required * **Quality**: Use clear, high-quality source videos * **Duration**: Maximum video duration is 120 seconds * **Motion**: The source video should contain the motion you want to apply to the character ### API Usage Tips * **Webhook**: Use the `webhookUrl` parameter to receive notifications when processing is complete * **Prompt**: Use the `prompt` parameter for generation guidance (max 500 characters) * **Resolution**: Choose appropriate resolution (480p or 720p) based on your needs - higher resolution may take longer to process * **Mode**: Choose between "animate" (character animation) or "replace" (face replacement) based on your use case * **Result Cleanup**: Save generated videos promptly as they expire after 7 days ## Common Use Cases ### Basic Character Animation Create a character animation video by applying motion from a source video: ```json theme={null} { "image": "https://example.com/character-image.png", "video": "https://example.com/source-video.mp4", "duration": 10, "resolution": "720p", "mode": "animate", "model_name": "wavespeed-ai/wan-2.2/animate", "webhookurl": "https://your-callback-url.com/webhook" } ``` ### Character Animation with Prompt Use the `prompt` parameter for enhanced control over the animation: ```json theme={null} { "image": "https://example.com/character-image.png", "video": "https://example.com/source-video.mp4", "duration": 15, "resolution": "720p", "mode": "animate", "prompt": "Smooth character animation with natural movement and expressive gestures", "model_name": "wavespeed-ai/wan-2.2/animate", "webhookurl": "" } ``` ### Face Replacement Mode Replace faces in a video with a character face: ```json theme={null} { "image": "https://example.com/character-face.png", "video": "https://example.com/target-video.mp4", "resolution": "720p", "mode": "replace", "model_name": "wavespeed-ai/wan-2.2/animate", "webhookurl": "" } ``` ## Notes * **Pro Plan Required**: Character Swap feature requires Pro plan or higher subscription * **Video Duration**: If not specified, the duration will be automatically detected from the source video. Maximum duration is 120 seconds * **Mode Options**: * `animate`: Applies character animation to the image using the video's motion * `replace`: Replaces faces in the video with the character from the image * **Webhook Callbacks**: If a webhook URL is provided, you will receive a POST request when the task status changes to completed (3) or failed (4) ## Support For additional help and examples, check out our: * [Authentication Guide](/authentication/usage) * [Webhook Documentation](/ai-tools-suite/webhook) # Create Character Swap Source: https://docs.akool.com/ai-tools-suite/character-swap/create Create animated video from character image and source video using WaveSpeed AI's advanced animation models The resources (image, video) generated by our API are valid for 7 days. Please save the relevant resources as soon as possible to prevent expiration. ## Endpoint ``` POST https://openapi.akool.com/api/open/v4/characterSwap/create ``` ## Request Headers | **Parameter** | **Value** | **Description** | | ------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | x-api-key | API Key | Your API Key used for request authorization. If both Authorization and x-api-key have values, Authorization will be used first and x-api-key will be discarded. | | Authorization | Bearer `{token}` | Your API Key used for request authorization.[Get Token](/authentication/usage#get-the-token) | ## Body Attributes | **Parameter** | **Type** | **Required** | **Description** | | ------------- | -------- | ------------ | ---------------------------------------------------------------------------------------------------- | | image | String | true | Character image URL (PNG or JPEG) to be animated | | video | String | true | Source video URL (MP4) with motion to apply | | duration | Number | false | Video duration in seconds (1-120). If not provided, will be automatically detected from the video | | resolution | String | false | Output resolution: 480p, 720p, 1080p (default: 720p) | | mode | String | false | Animation mode: "animate" (character animation) or "replace" (face replacement) (default: "animate") | | prompt | String | false | Optional prompt text for generation guidance (max 500 characters) | | webhookurl | String | false | Callback URL for POST requests | ## Response Attributes | **Parameter** | **Type** | **Description** | | ------------------- | -------- | ------------------------------------------------------------ | | code | Integer | Interface returns business status code (1000:success) | | msg | String | Interface returns status information | | data | Object | Response data object | | - \_id | String | Document ID | | - create\_time | Long | Creation timestamp | | - uid | Integer | User ID | | - team\_id | String | Team ID | | - status | Integer | Task status: 1=queueing, 2=processing, 3=completed, 4=failed | | - video\_duration | Number | Video duration in seconds | | - deduction\_credit | Integer | Credits deducted | | - resolution | String | Video resolution | | - file\_name | String | Output file name | | - image\_url | String | Input image URL | | - video\_url | String | Input video URL | | - prompt | String | Animation prompt | | - mode | String | Animation mode | | - model\_name | String | Model name used | | - webhookUrl | String | Callback URL | ## Example ### Request Body ```json theme={null} { "image": "https://drz0f01yeq1cx.cloudfront.net/character-image.png", "video": "https://drz0f01yeq1cx.cloudfront.net/source-video.mp4", "duration": 10, "resolution": "720p", "mode": "animate", "prompt": "Smooth character animation with natural movement", "webhookurl": "https://your-callback-url.com/webhook" } ``` ### Request ```bash cURL theme={null} curl --location 'https://openapi.akool.com/api/open/v4/characterSwap/create' \ --header 'x-api-key: {{API Key}}' \ --header 'Content-Type: application/json' \ --data '{ "image": "https://drz0f01yeq1cx.cloudfront.net/character-image.png", "video": "https://drz0f01yeq1cx.cloudfront.net/source-video.mp4", "duration": 10, "resolution": "720p", "mode": "animate", "prompt": "Smooth character animation with natural movement", "webhookurl": "https://your-callback-url.com/webhook" }' ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, "{\n \"image\": \"https://drz0f01yeq1cx.cloudfront.net/character-image.png\",\n \"video\": \"https://drz0f01yeq1cx.cloudfront.net/source-video.mp4\",\n \"duration\": 10,\n \"resolution\": \"720p\",\n \"mode\": \"animate\",\n \"prompt\": \"Smooth character animation with natural movement\",\n \"webhookurl\": \"https://your-callback-url.com/webhook\"\n}"); Request request = new Request.Builder() .url("https://openapi.akool.com/api/open/v4/characterSwap/create") .method("POST", body) .addHeader("x-api-key", "{{API Key}}") .addHeader("Content-Type", "application/json") .build(); Response response = client.newCall(request).execute(); ``` ```js Javascript theme={null} const myHeaders = new Headers(); myHeaders.append("x-api-key", "{{API Key}}"); myHeaders.append("Content-Type", "application/json"); const raw = JSON.stringify({ "image": "https://drz0f01yeq1cx.cloudfront.net/character-image.png", "video": "https://drz0f01yeq1cx.cloudfront.net/source-video.mp4", "duration": 10, "resolution": "720p", "mode": "animate", "prompt": "Smooth character animation with natural movement", "webhookurl": "https://your-callback-url.com/webhook" }); const requestOptions = { method: "POST", headers: myHeaders, body: raw, redirect: "follow" }; fetch("https://openapi.akool.com/api/open/v4/characterSwap/create", requestOptions) .then((response) => response.text()) .then((result) => console.log(result)) .catch((error) => console.error(error)); ``` ```php PHP theme={null} '{{API Key}}', 'Content-Type' => 'application/json' ]; $body = '{ "image": "https://drz0f01yeq1cx.cloudfront.net/character-image.png", "video": "https://drz0f01yeq1cx.cloudfront.net/source-video.mp4", "duration": 10, "resolution": "720p", "mode": "animate", "prompt": "Smooth character animation with natural movement", "webhookurl": "https://your-callback-url.com/webhook" }'; $request = new Request('POST', 'https://openapi.akool.com/api/open/v4/characterSwap/create', $headers, $body); $res = $client->sendAsync($request)->wait(); echo $res->getBody(); ?> ``` ```python Python theme={null} import requests import json url = "https://openapi.akool.com/api/open/v4/characterSwap/create" payload = json.dumps({ "image": "https://drz0f01yeq1cx.cloudfront.net/character-image.png", "video": "https://drz0f01yeq1cx.cloudfront.net/source-video.mp4", "duration": 10, "resolution": "720p", "mode": "animate", "prompt": "Smooth character animation with natural movement", "webhookurl": "https://your-callback-url.com/webhook" }) headers = { 'x-api-key':'{{API Key}}', 'Content-Type': 'application/json' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text) ``` ### Response ```json theme={null} { "code": 1000, "msg": "OK", "data": { "_id": "689174694b4dbdd4ab3d28c9", "create_time": 1754362985482, "uid": 101400, "team_id": "6805fb69e92d9edc7ca0b409", "status": 1, "video_duration": 10, "deduction_credit": 20, "resolution": "720p", "file_name": "CharacterSwap_1754362985482.mp4", "image_url": "https://drz0f01yeq1cx.cloudfront.net/character-image.png", "video_url": "https://drz0f01yeq1cx.cloudfront.net/source-video.mp4", "prompt": "Smooth character animation with natural movement", "mode": "animate", "model_name": "wavespeed-ai/wan-2.2/animate", "webhookUrl": "https://your-callback-url.com/webhook" } } ``` ## Important Notes * **Image Quality**: Use high-resolution images with clearly visible faces for better results * **Video Format**: MP4 format is required for source videos * **Duration**: If not specified, duration will be automatically detected from the source video. Maximum is 120 seconds * **Mode Options**: * `animate`: Applies character animation to the image using the video's motion * `replace`: Replaces faces in the video with the character from the image * **Prompt**: Use the `prompt` parameter for enhanced control over the animation (max 500 characters) * **Resolution**: Choose between 480p or 720p or 1080p based on your needs - higher resolution may take longer to process * **Resource Expiration**: Generated videos are valid for 7 days, save them promptly * **Webhook**: Use `webhookUrl` to receive notifications when video generation is complete * Save the `_id` from the response to check video status using the [Get Video Info Result](/ai-tools-suite/character-swap/get-result) API # Get Video Info Result Source: https://docs.akool.com/ai-tools-suite/character-swap/get-result Retrieve character swap video results by ID ## Endpoint ``` GET https://openapi.akool.com/api/open/v3/content/video/infobymodelid?video_model_id={{video_model_id}} ``` ## Request Headers | **Parameter** | **Value** | **Description** | | ------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | x-api-key | API Key | Your API Key used for request authorization. If both Authorization and x-api-key have values, Authorization will be used first and x-api-key will be discarded. | | Authorization | Bearer `{token}` | Your API Key used for request authorization.[Get Token](/authentication/usage#get-the-token) | ## Query Parameters | **Parameter** | **Type** | **Required** | **Description** | | ---------------- | -------- | ------------ | ---------------------------------------------------------------------------------------------- | | video\_model\_id | String | true | The `_id` returned from the [Create Character Swap API](/ai-tools-suite/character-swap/create) | ## Response Attributes | **Parameter** | **Type** | **Description** | | ------------------------ | -------- | ------------------------------------------------------- | | code | Integer | Interface returns business status code (1000:success) | | msg | String | Interface returns status information | | data | Object | Response data object | | - \_id | String | Document ID | | - create\_time | Long | Creation timestamp | | - uid | Integer | User ID | | - team\_id | String | Team ID | | - update\_time | Long | Last update time/completion time | | - video\_duration | Number | Actual video duration | | - webhookUrl | String | Callback URL | | - file\_name | String | File name | | - image\_url | String | Input image URL | | - video | String | Generated video URL (available when video\_status is 3) | | - video\_url | String | Input source video URL | | - prompt | String | Prompt text | | - resolution | String | Resolution | | - deduction\_credit | Integer | Actual credits deducted | | - video\_status | Integer | Status: 1=queueing, 2=processing, 3=completed, 4=failed | | - faceswap\_fail\_reason | String | Error reason (when video\_status is 4) | ## Example ### Request ```bash cURL theme={null} curl --location 'https://openapi.akool.com/api/open/v3/content/video/infobymodelid?video_model_id=689174694b4dbdd4ab3d28c9' \ --header 'x-api-key: {{API Key}}' ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); Request request = new Request.Builder() .url("https://openapi.akool.com/api/open/v3/content/video/infobymodelid?video_model_id=689174694b4dbdd4ab3d28c9") .method("GET", null) .addHeader("x-api-key", "{{API Key}}") .build(); Response response = client.newCall(request).execute(); ``` ```js Javascript theme={null} const myHeaders = new Headers(); myHeaders.append("x-api-key", "{{API Key}}"); const requestOptions = { method: "GET", headers: myHeaders, redirect: "follow" }; fetch("https://openapi.akool.com/api/open/v3/content/video/infobymodelid?video_model_id=689174694b4dbdd4ab3d28c9", requestOptions) .then((response) => response.text()) .then((result) => console.log(result)) .catch((error) => console.error(error)); ``` ```php PHP theme={null} '{{API Key}}' ]; $request = new Request('GET', 'https://openapi.akool.com/api/open/v3/content/video/infobymodelid?video_model_id=689174694b4dbdd4ab3d28c9', $headers); $res = $client->sendAsync($request)->wait(); echo $res->getBody(); ?> ``` ```python Python theme={null} import requests url = "https://openapi.akool.com/api/open/v3/content/video/infobymodelid?video_model_id=689174694b4dbdd4ab3d28c9" headers = { 'x-api-key':'{{API Key}}' } response = requests.request("GET", url, headers=headers) print(response.text) ``` ### Response #### Queueing Status (video\_status = 1) ```json theme={null} { "code": 1000, "msg": "OK", "data": { "_id": "689174694b4dbdd4ab3d28c9", "create_time": 1754362985482, "uid": 101400, "team_id": "6805fb69e92d9edc7ca0b409", "video_duration": 10, "webhookUrl": "https://your-callback-url.com/webhook", "file_name": "CharacterSwap_1754362985482.mp4", "image_url": "https://drz0f01yeq1cx.cloudfront.net/character-image.png", "video_url": "https://drz0f01yeq1cx.cloudfront.net/source-video.mp4", "prompt": "Smooth character animation with natural movement", "resolution": "720p", "deduction_credit": 20, "video_status": 1 } } ``` #### Completed Status (video\_status = 3) ```json theme={null} { "code": 1000, "msg": "OK", "data": { "_id": "689174694b4dbdd4ab3d28c9", "create_time": 1754362985482, "uid": 101400, "team_id": "6805fb69e92d9edc7ca0b409", "update_time": 1754363095482, "video_duration": 10.5, "webhookUrl": "https://your-callback-url.com/webhook", "file_name": "CharacterSwap_1754362985482.mp4", "image_url": "https://drz0f01yeq1cx.cloudfront.net/character-image.png", "video": "https://d2qf6ukcym4kn9.cloudfront.net/1754363091791-1423.mp4", "video_url": "https://drz0f01yeq1cx.cloudfront.net/source-video.mp4", "prompt": "Smooth character animation with natural movement", "resolution": "720p", "deduction_credit": 20, "video_status": 3 } } ``` #### Failed Status (video\_status = 4) ```json theme={null} { "code": 1000, "msg": "OK", "data": { "_id": "689174694b4dbdd4ab3d28c9", "create_time": 1754362985482, "uid": 101400, "team_id": "6805fb69e92d9edc7ca0b409", "update_time": 1754363095482, "video_duration": 10, "webhookUrl": "https://your-callback-url.com/webhook", "file_name": "CharacterSwap_1754362985482.mp4", "image_url": "https://drz0f01yeq1cx.cloudfront.net/character-image.png", "video_url": "https://drz0f01yeq1cx.cloudfront.net/source-video.mp4", "prompt": "Smooth character animation with natural movement", "resolution": "720p", "deduction_credit": 0, "video_status": 4, "faceswap_fail_reason": "Failed to process the video. Please check your input resources." } } ``` ## Video Status | Status | Description | | ------ | -------------------------------------------------------------------------- | | 1 | In Queue - Your request is waiting to be processed | | 2 | Processing - Video is currently being generated | | 3 | Success - Video completed, result URL is available in the `video` field | | 4 | Failed - Video generation failed, check `faceswap_fail_reason` for details | ## Important Notes * Use the `_id` field from the [Create Character Swap API](/ai-tools-suite/character-swap/create) response as the `video_model_id` parameter * Poll this endpoint periodically to check the video generation status * When `video_status` is 3 (Success), the `video` field will contain the URL of the generated video * Generated videos are valid for 7 days, download and save them promptly * If a webhook URL was provided during creation, you will receive a callback when the task completes (no need to poll) # ErrorCode Source: https://docs.akool.com/ai-tools-suite/error-code Error codes and meanings **Response Code Description** Please note that if the value of the response code is not equal to 1000, the request is failed or wrong | **Parameter** | **Value** | **Description** | | ------------- | --------- | ------------------------------------------ | | code | 1000 | Success | | code | 1003 | Parameter error | | code | 1004 | Requires verification | | code | 1005 | Frequent operation | | code | 1006 | Insufficient quota balance | | code | 1007 | Face count changes exceed | | code | 1008 | content not exist | | code | 1009 | permission denied | | code | 1010 | This content cannot be operated | | code | 1011 | This content has been operated | | code | 1013 | Use audio in video | | code | 1014 | Resource does not exist | | code | 1015 | Video processing error | | code | 1016 | Face swapping error | | code | 1017 | Audio not created | | code | 1101 | Illegal token | | code | 1102 | token cannot be empty | | code | 1103 | Not paid or payment is overdue | | code | 1104 | Insufficient credit balance | | code | 1105 | avatar processing error | | code | 1108 | image processing error | | code | 1109 | account not exist | | code | 1110 | audio processing error | | code | 1111 | avatar callback processing error | | code | 1112 | voice processing error | | code | 1200 | Account blocked | | code | 1201 | create audio processing error | | code | 1202 | Video lip sync same language out of range | | code | 1203 | Using Video and Audio | | code | 1204 | video duration exceed | | code | 1205 | create video processing error | | code | 1206 | backgroound change processing error | | code | 1207 | video size exceed | | code | 1208 | video parsing error | | code | 1209 | The video encoding format is not supported | | code | 1210 | video fps exceed | | code | 1211 | Creating lip sync errors | | code | 1212 | Sentiment analysis fails | | code | 1213 | Requires subscription user to use | | code | 1214 | liveAvatar in processing | | code | 1215 | liveAvatar processing is busy | | code | 1216 | liveAvatar session not exist | | code | 1217 | liveAvatar callback error | | code | 1218 | liveAvatar processing error | | code | 1219 | liveAvatar closed | | code | 1220 | liveAvatar upload avatar error | | code | 1221 | Account not subscribed | | code | 1222 | Resource already exist | | code | 1223 | liveAvatar upload exceed | # Face Detection API Overview Source: https://docs.akool.com/ai-tools-suite/face-detection Comprehensive guide to the Face Detection API Detect faces in images and videos with high accuracy. Get bounding boxes, 6-point landmarks, cropped face images, and face tracking for video content. ## API Endpoints ### Face Detection Operations * [Detect Faces](/ai-tools-suite/face-detection/detect-faces) - Unified endpoint for face detection in images and videos (auto-detects media type) * [Analyze Frames](/ai-tools-suite/face-detection/analyze-frames) - Multi-frame face analysis with person deduplication for face swap preparation ## Getting Started ### Basic Workflow 1. **For Image Face Detection**: * Call the [Detect Faces API](/ai-tools-suite/face-detection/detect-faces) with an image URL or base64-encoded image * Only the `url` or `img` parameter is required (no need for `num_frames`) * Receive bounding boxes and 6-point landmarks for all detected faces * Optionally get cropped face image URLs with `return_face_url=true` * Use the landmark data for downstream tasks (e.g., face swap, face recognition) 2. **For Video Face Detection**: * Call the [Detect Faces API](/ai-tools-suite/face-detection/detect-faces) with a video URL * Specify the `num_frames` parameter to control how many frames to analyze (default: 5) * Get face tracking data across frames with removed face positions ### Response Code Description Error code 0 indicates success. Any non-zero error code indicates a failure. Check the error\_msg field for detailed error information. | Code | Description | | ---- | ------------------------------------ | | 0 | Success | | 1 | Error - Check error\_msg for details | ## Features ### Dual Input Modes The API supports two ways to provide image input: 1. **URL Mode**: Provide a publicly accessible URL to an image or video 2. **Base64 Mode**: Provide base64-encoded image data (with or without data URI prefix) ```json theme={null} // URL mode { "url": "https://example.com/image.jpg" } // Base64 mode { "img": "data:image/jpeg;base64,/9j/4AAQSkZJRg..." } ``` ### 6-Point Facial Landmarks The API detects 6 key facial landmarks for each face: 1. **Left Eye** - Center point of the left eye 2. **Right Eye** - Center point of the right eye 3. **Nose Tip** - Tip of the nose 4. **Mouth Center** - Center point of the mouth (X-axis midpoint between mouth corners) 5. **Left Mouth Corner** - Left corner of the mouth 6. **Right Mouth Corner** - Right corner of the mouth ### Cropped Face Images When `return_face_url=true`, the API returns: * **face\_urls**: URLs to cropped face images stored in cloud storage * **crop\_region**: The region coordinates used for cropping * **crop\_landmarks**: Landmarks relative to the cropped image This is particularly useful for face swap operations where you need both the face image and its landmarks. ### Single Face Mode When `single_face=true`, the API returns only the largest face (by area) in each frame. This is useful for: * Portrait photos where you only care about the main subject * ID photos with a single person * Reducing response size when multiple faces are detected ### Face Tracking for Videos For video content, the API provides advanced face tracking: * **Persistent Face IDs** - Tracks the same face across multiple frames * **Removed Faces** - Identifies faces that were present in previous frames but are no longer visible * **Frame Timing** - Provides timestamp information for each frame ### Auto Media Type Detection The API automatically detects whether the input is an image or video based on: * File extension (`.jpg`, `.png`, `.mp4`, `.mov`, etc.) * Content-Type header from the URL * Fallback to content analysis if needed ## Best Practices ### Image Requirements * **Quality**: Use high-resolution images for better detection accuracy * **Face Visibility**: Ensure faces are clearly visible and not obscured * **Lighting**: Well-lit images produce better detection results * **Angle**: Frontal or slight angle faces work best (±45 degrees) * **Size**: Face size should be at least 80x80 pixels ### Video Requirements * **Duration**: Shorter videos process faster * **Frame Rate**: Standard frame rates (24-30 fps) are optimal * **Resolution**: 720p or higher recommended for best results * **Face Count**: API can detect multiple faces per frame * **Encoding**: Use standard encoding formats (H.264 recommended) ### API Usage Tips * **Parameter Usage**: * **For Images**: Only `url` or `img` parameter is required. The `num_frames` parameter is NOT needed. * **For Videos**: Both `url` and `num_frames` parameters are recommended. * **Frame Selection** (for videos only): * Short videos (\< 10s): 5-10 frames * Medium videos (10-30s): 10-20 frames * Long videos (> 30s): 20-50 frames * **URL Accessibility**: Ensure the media URL is publicly accessible * **Supported Formats**: * Images: JPG, JPEG, PNG, BMP, WEBP * Videos: MP4, MOV, AVI, WEBM ## Understanding the Response ### Response Structure ```json theme={null} { "error_code": 0, "error_msg": "SUCCESS", "faces_obj": { "0": { "landmarks": [ [[100, 120], [150, 120], [125, 150], [125, 180], [110, 180], [140, 180]] ], "landmarks_str": [ "100,120:150,120:125,150:125,180" ], "region": [[80, 100, 100, 120]], "removed": [], "frame_time": null, "face_urls": null, "crop_region": null, "crop_landmarks": null } } } ``` ### Field Descriptions * **error\_code**: Status code (0 = success) * **error\_msg**: Status message or error description * **faces\_obj**: Dictionary keyed by frame index (as string) * **landmarks**: Array of 6-point landmarks for each detected face * Format: `[[x1, y1], [x2, y2], [x3, y3], [x4, y4], [x5, y5], [x6, y6]]` * **landmarks\_str**: String format of first 4 landmarks for Face Swap API compatibility * Format: `"x1,y1:x2,y2:x3,y3:x4,y4"` * **region**: Bounding boxes for each detected face * Format: `[x, y, width, height]` where (x, y) is the top-left corner * **removed**: Bounding boxes of faces no longer visible (video only) * **frame\_time**: Timestamp in seconds for this frame (video only, null for images) * **face\_urls**: Cropped face image URLs (only when `return_face_url=true`) * **crop\_region**: Cropping region in original image (only when `return_face_url=true`) * **crop\_landmarks**: Landmarks relative to cropped image (only when `return_face_url=true`) ## Common Use Cases ### Face Detection for Image Processing ```json theme={null} { "url": "https://example.com/portrait.jpg" } ``` **Use case**: Detect faces in a portrait photo for face alignment, face recognition, or face swap preprocessing. For images, the `num_frames` parameter is not needed and will be ignored. ### Get Cropped Face Images for Face Swap ```json theme={null} { "url": "https://example.com/photo.jpg", "return_face_url": true } ``` **Use case**: Get cropped face images with their landmarks for direct use in Face Swap API. ### Face Tracking in Video Content ```json theme={null} { "url": "https://example.com/video.mp4", "num_frames": 15 } ``` Use case: Track faces across video frames for video editing, face swap in videos, or facial animation. ### Single Face Detection ```json theme={null} { "url": "https://example.com/group_photo.jpg", "single_face": true } ``` Use case: Get only the main/largest face from a group photo. ### Multiple Face Detection The API automatically detects all faces in an image or video frame. No special configuration needed. ### Integration with Face Swap 1. Use Face Detection API to get face landmarks and optionally cropped face URLs 2. Pass the `landmarks_str` value to Face Swap API as the `opts` parameter 3. When using `return_face_url=true`, use `crop_landmarks` for the cropped face image ## Error Handling ### Common Errors | Error Message | Cause | Solution | | -------------------------------------------------- | ------------------------------ | ----------------------------------------------------------- | | "Either 'url' or 'img' parameter must be provided" | Missing input | Provide either `url` or `img` parameter | | "Invalid URL format" | Malformed URL provided | Ensure URL is properly formatted with protocol (http/https) | | "Failed to download media" | URL inaccessible or invalid | Verify URL is publicly accessible | | "No faces detected" | No faces found in media | Check image quality and face visibility | | "Failed to process media" | Media format not supported | Use supported formats (JPG, PNG, MP4, etc.) | | "Media type detection failed" | Unable to determine media type | Ensure file has proper extension or content-type | ### Handling Failed Requests ```python theme={null} # Example error handling in Python # For image detection (no num_frames needed) response = requests.post( "https://openapi.akool.com/interface/detect-api/detect_faces", json={"url": "https://example.com/image.jpg"}, headers={"x-api-key": "YOUR_API_KEY"} ) # For video detection (num_frames recommended) # response = requests.post( # "https://openapi.akool.com/interface/detect-api/detect_faces", # json={"url": "https://example.com/video.mp4", "num_frames": 10}, # headers={"x-api-key": "YOUR_API_KEY"} # ) result = response.json() if result["error_code"] != 0: print(f"Error: {result['error_msg']}") else: faces = result["faces_obj"] print(f"Detected {len(faces['0']['landmarks'])} faces") ``` ## Performance Considerations ### Processing Time * **Images**: Typically \< 1 second * **Videos**: Varies based on: * Number of frames requested * Video resolution * Number of faces per frame ### Rate Limits Rate limits apply to all API endpoints. Please refer to your account settings for specific limits. ### Optimization Tips * Use appropriate `num_frames` value - more frames = longer processing time * Use `single_face=true` when you only need one face * Cache results when processing the same media multiple times * Process videos in batches if analyzing many videos ## Support For additional help and examples, check out: * [Authentication Guide](/authentication/usage) * [API Error Codes](/ai-tools-suite/error-code) * [Face Swap Integration](/ai-tools-suite/faceswap) Need help? Contact us at [info@akool.com](mailto:info@akool.com) # Analyze Frames Source: https://docs.akool.com/ai-tools-suite/face-detection/analyze-frames POST /faceswap/analyze_frames Face analysis for single or multiple images with automatic person deduplication Analyze faces in one or more images, returning a `persons` format optimized for face swap. Automatically deduplicates faces across multiple frames. ## Request Parameters | Parameter | Type | Required | Default | Description | | -------------- | ------ | -------- | ---------------- | ----------------------------------- | | `frame_urls` | array | Yes | - | List of image URLs to analyze | | `timestamps` | array | No | \[0.0, 1.0, ...] | Timestamps for each frame (seconds) | | `expand_ratio` | number | No | 0.3 | Face crop expansion ratio (0-1) | **Single Image**: Each face becomes a separate person (no deduplication). **Multiple Images**: Same person across frames is merged into one entry. ## Response Format ```json theme={null} { "success": true, "frame_count": 3, "persons": [ { "person_id": "person_0", "index": 0, "face_url": "https://s3.example.com/faces/face_abc123.jpg", "bbox": [100, 50, 200, 180], "confidence": 0.95, "appearances": [ {"timestamp": 0.0, "frame_idx": 0, "bbox": [100, 50, 200, 180]}, {"timestamp": 1.0, "frame_idx": 1, "bbox": [105, 52, 205, 182]} ], "first_seen": 0.0, "last_seen": 1.0 } ] } ``` ### Response Fields | Field | Type | Description | | ------------- | ------- | -------------------------- | | `success` | boolean | Whether analysis succeeded | | `frame_count` | integer | Number of frames analyzed | | `persons` | array | List of detected persons | ### Person Object | Field | Type | Description | | ------------- | ------- | ---------------------------------------------------------- | | `person_id` | string | Unique identifier (e.g., "person\_0") | | `index` | integer | Sort index (left to right by x-coordinate) | | `face_url` | string | Cropped face image URL | | `bbox` | array | Bounding box `[x1, y1, x2, y2]` from first appearance | | `confidence` | number | Detection confidence (0-1) | | `appearances` | array | List of frame appearances with timestamp, frame\_idx, bbox | | `first_seen` | number | First appearance timestamp | | `last_seen` | number | Last appearance timestamp | ## Examples ### Example 1: Single Image Analysis **Request:** ```json theme={null} { "frame_urls": ["https://example.com/group_photo.jpg"] } ``` **Response:** ```json theme={null} { "success": true, "frame_count": 1, "persons": [ { "person_id": "person_0", "index": 0, "face_url": "https://s3.example.com/faces/face_a1b2c3.jpg", "bbox": [100, 50, 200, 180], "confidence": 0.96, "appearances": [ {"timestamp": 0.0, "frame_idx": 0, "bbox": [100, 50, 200, 180]} ], "first_seen": 0.0, "last_seen": 0.0 }, { "person_id": "person_1", "index": 1, "face_url": "https://s3.example.com/faces/face_d4e5f6.jpg", "bbox": [300, 60, 400, 190], "confidence": 0.94, "appearances": [ {"timestamp": 0.0, "frame_idx": 0, "bbox": [300, 60, 400, 190]} ], "first_seen": 0.0, "last_seen": 0.0 } ] } ``` ### Example 2: Multi-Frame Analysis (Video Frames) **Request:** ```json theme={null} { "frame_urls": [ "https://example.com/frame_0.jpg", "https://example.com/frame_1.jpg", "https://example.com/frame_2.jpg" ], "timestamps": [0.0, 1.0, 2.0] } ``` **Response:** ```json theme={null} { "success": true, "frame_count": 3, "persons": [ { "person_id": "person_0", "index": 0, "face_url": "https://s3.example.com/faces/face_abc123.jpg", "bbox": [100, 50, 200, 180], "confidence": 0.95, "appearances": [ {"timestamp": 0.0, "frame_idx": 0, "bbox": [100, 50, 200, 180]}, {"timestamp": 1.0, "frame_idx": 1, "bbox": [105, 52, 205, 182]}, {"timestamp": 2.0, "frame_idx": 2, "bbox": [110, 55, 210, 185]} ], "first_seen": 0.0, "last_seen": 2.0 } ] } ``` The same person appearing in all 3 frames is merged into a single person entry with multiple appearances. ### Example 3: Custom Expand Ratio **Request:** ```json theme={null} { "frame_urls": ["https://example.com/photo.jpg"], "expand_ratio": 0.5 } ``` ## Error Responses | success | error | Description | | ------- | --------------------------------------------- | ------------------- | | false | frame\_urls is required and must not be empty | Missing frame\_urls | | false | Failed to download image from URL | Download failed | | true | (empty persons array) | No faces detected | ## Integration with Face Swap ```python theme={null} import requests # Analyze frames response = requests.post( "https://openapi.akool.com/interface/detect-api/faceswap/analyze_frames", json={"frame_urls": ["https://example.com/target.jpg"]}, headers={"x-api-key": "YOUR_API_KEY"} ) result = response.json() if result["success"]: for person in result["persons"]: face_url = person["face_url"] print(f"Person {person['person_id']}: {face_url}") # Use face_url directly in Face Swap API ``` ## Best Practices * **URL Requirements**: Use HTTPS, ensure publicly accessible * **Multi-Frame**: Use 3-10 frames for typical video clips * **Expand Ratio**: Use 0.5 for more facial context in face swap # Detect Faces Source: https://docs.akool.com/ai-tools-suite/face-detection/detect-faces POST /detect_faces Unified endpoint to detect faces in either video or image from URL or base64-encoded image Detect faces in images and videos with 6-point landmarks. Supports URL and base64 input, with optional cropped face URLs. ## Request Parameters | Parameter | Type | Required | Default | Description | | ----------------- | ------- | -------- | ------- | ---------------------------------------- | | `url` | string | Yes\* | - | Image or video URL (publicly accessible) | | `img` | string | Yes\* | - | Base64-encoded image data | | `num_frames` | integer | No | 5 | Number of frames for video analysis | | `return_face_url` | boolean | No | false | Return cropped face image URLs | | `single_face` | boolean | No | false | Return only the largest face | Either `url` or `img` must be provided. If both are provided, `url` takes priority. ## Response Format ```json theme={null} { "error_code": 0, "error_msg": "SUCCESS", "faces_obj": { "0": { "landmarks": [[[120, 85], [180, 88], [150, 130], [150, 165], [125, 165], [175, 168]]], "landmarks_str": ["120,85:180,88:150,130:150,165"], "region": [[80, 50, 150, 180]], "removed": [], "frame_time": null, "face_urls": null, "crop_region": null, "crop_landmarks": null } } } ``` ### Response Fields | Field | Type | Description | | ------------ | ------- | ----------------------------------------------- | | `error_code` | integer | 0 = success, 1 = error | | `error_msg` | string | Status message | | `faces_obj` | object | Face data keyed by frame index ("0", "1", etc.) | ### Face Frame Data | Field | Type | Description | | ---------------- | ----------- | --------------------------------------------------------------------------------------------------------------- | | `landmarks` | array | 6-point landmarks for each face: Left Eye, Right Eye, Nose, Mouth Center, Left Mouth Corner, Right Mouth Corner | | `landmarks_str` | array | First 4 landmarks as string format `"x1,y1:x2,y2:x3,y3:x4,y4"` - use this for Face Swap `opts` parameter | | `region` | array | Bounding boxes `[x, y, width, height]` | | `removed` | array | Faces no longer visible (video only) | | `frame_time` | number/null | Timestamp in seconds (video only, null for images) | | `face_urls` | array/null | Cropped face URLs (when `return_face_url=true`) | | `crop_region` | array/null | Crop region in original image coordinates | | `crop_landmarks` | array/null | Landmarks relative to cropped image | ## Examples ### Example 1: Basic Image Detection **Request:** ```json theme={null} { "url": "https://example.com/photo.jpg" } ``` **Response:** ```json theme={null} { "error_code": 0, "error_msg": "SUCCESS", "faces_obj": { "0": { "landmarks": [[[320, 240], [420, 240], [370, 300], [370, 350], [340, 350], [400, 350]]], "landmarks_str": ["320,240:420,240:370,300:370,350"], "region": [[300, 200, 150, 180]], "removed": [], "frame_time": null } } } ``` ### Example 2: Video Detection **Request:** ```json theme={null} { "url": "https://example.com/video.mp4", "num_frames": 10 } ``` ### Example 3: Get Cropped Face URLs **Request:** ```json theme={null} { "url": "https://example.com/photo.jpg", "return_face_url": true } ``` **Response:** ```json theme={null} { "error_code": 0, "error_msg": "SUCCESS", "faces_obj": { "0": { "landmarks": [[[120, 85], [180, 88], [150, 130], [150, 165], [125, 165], [175, 168]]], "landmarks_str": ["120,85:180,88:150,130:150,165"], "region": [[80, 50, 150, 180]], "removed": [], "frame_time": null, "face_urls": ["https://s3.example.com/faces/face_detect_0.jpg"], "crop_region": [[30, 0, 250, 280]], "crop_landmarks": ["90,85:150,88:120,130:120,165"] } } } ``` ### Example 4: Single Face Mode **Request:** ```json theme={null} { "url": "https://example.com/group_photo.jpg", "single_face": true } ``` ## Error Responses | error\_code | error\_msg | Description | | ----------- | ------------------------------------------------ | --------------- | | 0 | SUCCESS | Success | | 1 | Either 'url' or 'img' parameter must be provided | Missing input | | 1 | Invalid URL format | Bad URL | | 1 | Failed to download media from URL | Download failed | ## Integration with Face Swap Use `landmarks_str` directly as the `opts` parameter in Face Swap API: ```python theme={null} import requests # Detect faces response = requests.post( "https://openapi.akool.com/interface/detect-api/detect_faces", json={"url": "https://example.com/target.jpg", "return_face_url": True}, headers={"x-api-key": "YOUR_API_KEY"} ) result = response.json() if result["error_code"] == 0: frame_data = result["faces_obj"]["0"] # Use for Face Swap API target_image = { "path": frame_data["face_urls"][0], "opts": frame_data["crop_landmarks"][0] } ``` ## Best Practices * **URL Requirements**: Use HTTPS, ensure publicly accessible * **Video num\_frames**: Short videos (5-10), Medium (10-20), Long (20-50) * **Performance**: Use `single_face=true` when only one face needed # Face Swap API Overview Source: https://docs.akool.com/ai-tools-suite/faceswap Comprehensive guide to the Face Swap API The resources (image, video, voice) generated by our API are valid for 7 days. Please save the relevant resources as soon as possible to prevent expiration. Experience our face swap technology in action by exploring our interactive demo on GitHub: [AKool Face Swap Demo](https://github.com/AKOOL-Official/akool-face-swap-demo). ## API Endpoints ### Face Swap Operations * [Image Faceswap](/ai-tools-suite/faceswap/image-faceswap) - Swap faces in images with high quality (supports multiple faces) * [Face Swap Pro](/ai-tools-suite/faceswap/image-faceswap-v4) - **⭐ NEW** More realistic, more similar - Single face only (V4) * [Video Faceswap](/ai-tools-suite/faceswap/video-faceswap) - Swap faces in videos with high quality ### Result Management * [Get Faceswap Result List](/ai-tools-suite/faceswap/get-result) - Retrieve faceswap results by IDs * [Delete Faceswap Results](/ai-tools-suite/faceswap/delete-result) - Delete faceswap results by IDs ### Account Management * [Get User Credit Info](/ai-tools-suite/faceswap/get-credit) - Get faceswap user credit information ### Utilities * [Face Detect](/ai-tools-suite/faceswap/face-detect) - Detect faces in images and get landmark information (required for v3 APIs) ## Getting Started ### Basic Workflow 1. **For V3 APIs (Image/Video Faceswap)**: * Use the [Face Detect API](/ai-tools-suite/faceswap/face-detect) to detect faces and get landmark data * Use the `landmarks_str` value from the response as the `opts` parameter * Call the [Image Faceswap](/ai-tools-suite/faceswap/image-faceswap) or [Video Faceswap](/ai-tools-suite/faceswap/video-faceswap) API 2. **For Face Swap Pro (V4 API)** - More Realistic, More Similar: * Directly call the [Face Swap Pro API](/ai-tools-suite/faceswap/image-faceswap-v4) without face detection * Delivers more realistic and more similar face swap results * **Only supports single face swapping** 3. **Check Results**: * Use the [Get Result API](/ai-tools-suite/faceswap/get-result) to check the status of your face swap job * Download the result URL when the status is "Success" (status = 3) ### Response Code Description Please note that if the value of the response code is not equal to 1000, the request has failed or encountered an error. | Code | Description | | ---- | --------------------------------------------------------------------- | | 1000 | Success | | 1003 | Parameter error or Parameter cannot be empty | | 1005 | Operation is too frequent | | 1006 | Your quota is not enough | | 1007 | The number of people who can have their faces changed cannot exceed 8 | | 1101 | Invalid authorization or The request token has expired | | 1102 | Authorization cannot be empty | | 1200 | The account has been banned | ## Face Swap Status Codes When checking results, the `faceswap_status` field indicates the current state: | Status | Description | | ------ | --------------------------------------------------------- | | 1 | In Queue - Your request is waiting to be processed | | 2 | Processing - Face swap is currently being generated | | 3 | Success - Face swap completed, result URL is available | | 4 | Failed - Face swap failed, please check your input images | ## Best Practices ### Image Requirements * **Quality**: Use high-resolution images for better results * **Face Visibility**: Ensure faces are clearly visible and not obscured * **Lighting**: Well-lit images produce better face swap results * **Angle**: Frontal or slight angle faces work best ### Video Requirements * **Duration**: Keep videos under 60 seconds for optimal processing time * **Face Count**: For best results, limit to 8 or fewer faces * **Resolution**: Higher resolution videos may take longer to process * **Encoding**: Use standard encoding formats (H.264 recommended) ### API Usage Tips * **Webhook**: Use the `webhookUrl` parameter to receive notifications when processing is complete * **Face Enhancement**: Enable `face_enhance` for better quality results (may increase processing time) * **Credit Management**: Check your credit balance regularly using the [Get Credit API](/ai-tools-suite/faceswap/get-credit) * **Result Cleanup**: Delete old results using the [Delete Result API](/ai-tools-suite/faceswap/delete-result) to keep your account organized ## Common Use Cases ### Face Swap Pro - More Realistic, More Similar (Single Face Only) Use the [Face Swap Pro API](/ai-tools-suite/faceswap/image-faceswap-v4) for the most realistic and similar results with the simplest implementation: ```json theme={null} { "targetImage": [ { "path": "https://example.com/original.jpg" } ], "sourceImage": [ { "path": "https://example.com/replacement-face.jpg" } ], "model_name": "akool_faceswap_image_hq", "face_enhance": false } ``` ### Multiple Face Swap (V3 Required) Use the [V3 Image Faceswap API](/ai-tools-suite/faceswap/image-faceswap) when you need to swap multiple faces in one image: 1. Detect all faces using [Face Detect API](/ai-tools-suite/faceswap/face-detect) 2. Provide the `opts` parameter for each face 3. Ensure source and target arrays are properly aligned ### Video Face Swap Use the [Video Faceswap API](/ai-tools-suite/faceswap/video-faceswap) for video content: 1. Detect faces in a representative frame 2. Provide face landmarks for both source and target 3. Monitor processing status as video face swaps take longer ## Support For additional help and examples, check out our: * [GitHub Demo](https://github.com/AKOOL-Official/akool-face-swap-demo) * [Authentication Guide](/authentication/usage) * [Webhook Documentation](/ai-tools-suite/webhook) # Delete Faceswap Results Source: https://docs.akool.com/ai-tools-suite/faceswap/delete-result POST /api/open/v3/faceswap/result/delbyids Delete faceswap results by IDs ## Important Notes * Result IDs should be comma-separated strings * You can get the `_id` field from [Image Faceswap](/ai-tools-suite/faceswap/image-faceswap) or [Video Faceswap](/ai-tools-suite/faceswap/video-faceswap) API responses * This operation is irreversible - deleted results cannot be recovered # Face Detect (Legacy) Source: https://docs.akool.com/ai-tools-suite/faceswap/face-detect POST /detect Detect faces in images and get landmark information **This endpoint will be deprecated in a future release.** We recommend using the new [Detect Faces API](/ai-tools-suite/face-detection/detect-faces) for all new integrations. The new endpoint provides: * Support for both images and videos * Base64 image input support * Cropped face image URLs (`return_face_url` option) * Single face mode (`single_face` option) * Better face tracking for videos * Improved performance and accuracy **Recommended Migration**: Replace `https://sg3.akool.com/detect` with `https://openapi.akool.com/interface/detect-api/detect_faces` ## Migration Guide ### Old Request (Legacy) ```json theme={null} POST https://sg3.akool.com/detect { "single_face": false, "image_url": "https://example.com/image.jpg" } ``` ### New Request (Recommended) ```json theme={null} POST https://openapi.akool.com/interface/detect-api/detect_faces { "url": "https://example.com/image.jpg", "single_face": false } ``` ### Parameter Mapping | Legacy Parameter | New Parameter | Notes | | ---------------- | ----------------- | -------------------------- | | `image_url` | `url` | Renamed | | `img` | `img` | Same | | `single_face` | `single_face` | Same | | - | `num_frames` | New: for video support | | - | `return_face_url` | New: get cropped face URLs | ### Response Changes The new API returns a slightly different response format: **Legacy Response**: ```json theme={null} { "error_code": 0, "error_msg": "", "landmarks": [...], "landmarks_str": [...], "region": [...], "seconds": 0.123, "trx_id": "xxx" } ``` **New Response**: ```json theme={null} { "error_code": 0, "error_msg": "SUCCESS", "faces_obj": { "0": { "landmarks": [...], "landmarks_str": [...], "region": [...], "removed": [], "frame_time": null, "face_urls": null, "crop_region": null, "crop_landmarks": null } } } ``` The new API wraps face data in a `faces_obj` object keyed by frame index. For images, use `faces_obj["0"]` to access the face data. *** ## Legacy API Documentation The following documentation is for the legacy endpoint. For new integrations, we recommend using the [new Detect Faces API](/ai-tools-suite/face-detection/detect-faces). ## Important Notes * **single\_face**: Set to `true` to return only the largest face data, or `false` to return all detected faces. This parameter controls whether the API returns data for multiple faces or just the most prominent one. * **image\_url** or **img**: You can choose to enter either the image URL or the base64 encoded image data * The `landmarks_str` value from the response should be used as the `opts` parameter in Face Swap APIs ## Response Fields * **landmarks**: Array of face landmark coordinates * **landmarks\_str**: String representation of landmarks (use this for `opts` parameter) * **region**: Face region bounding box coordinates * **seconds**: API processing time * **trx\_id**: Transaction ID for tracking ## Face Detect Response Code | Error Code | Description | | ---------- | ---------------------------- | | 0 | Success | | Other | Check error\_msg for details | # Get User Credit Info Source: https://docs.akool.com/ai-tools-suite/faceswap/get-credit GET /api/open/v3/faceswap/quota/info Get faceswap user credit information ## Important Notes * This endpoint returns your current account balance * Credits are deducted when you submit faceswap requests * Monitor your credit balance to ensure uninterrupted service # Get Faceswap Result List Source: https://docs.akool.com/ai-tools-suite/faceswap/get-result GET /api/open/v3/faceswap/result/listbyids Get faceswap results by IDs ## Important Notes * Result IDs should be comma-separated strings * You can get the `_id` field from [Image Faceswap](/ai-tools-suite/faceswap/image-faceswap) or [Video Faceswap](/ai-tools-suite/faceswap/video-faceswap) API responses ## Faceswap Status | Status | Description | | ------ | ----------- | | 1 | In Queue | | 2 | Processing | | 3 | Success | | 4 | Failed | # Image Faceswap Source: https://docs.akool.com/ai-tools-suite/faceswap/image-faceswap POST /api/open/v3/faceswap/highquality/specifyimage Swap faces in images with high quality The resources (image, video, voice) generated by our API are valid for 7 days. Please save the relevant resources as soon as possible to prevent expiration. Experience our face swap technology in action by exploring our interactive demo on GitHub: [AKool Face Swap Demo](https://github.com/AKOOL-Official/akool-face-swap-demo). ## Important Notes * You can get the `opts` parameter (landmarks\_str) through the [Face Detect API](/ai-tools-suite/faceswap/face-detect) * The Face Detect API returns a `landmarks_str` value that should be used as the value of `opts` * When using [Face Detect API](/ai-tools-suite/faceswap/face-detect), set `single_face: true` to return only the largest face data, or `false` to return all detected faces * Ensure that the targetImage and sourceImage arrays are properly aligned and correspond to each other * **Model Selection**: To use different face swap models available on the official website, set `face_enhance: 0` for **Classic Model**, and `face_enhance: 1` for **HD Optimized** model. For **Clarity Boost** and **Identity Keeper** models, please contact our sales and technical support team # Face Swap Pro Source: https://docs.akool.com/ai-tools-suite/faceswap/image-faceswap-v4 POST /api/open/v4/faceswap/faceswapByImage Single face swap API - More Realistic, More Similar The resources (image, video, voice) generated by our API are valid for 7 days. Please save the relevant resources as soon as possible to prevent expiration. **Single Face Only**: This API is specifically designed for single face swapping scenarios. For multiple faces, please use the [V3 Image Faceswap API](/ai-tools-suite/faceswap/image-faceswap). ## Face Swap Pro - More Realistic, More Similar Face Swap Pro (V4 API) delivers superior face swap results with exceptional quality: * **🎯 More Realistic**: Advanced algorithm produces incredibly natural and lifelike face swaps * **✨ More Similar**: Enhanced matching technology ensures the swapped face closely resembles the target * **🚀 Higher Accuracy**: Superior facial feature alignment for better results * **⚡ Simplified Integration**: No need for the `opts` parameter or face detection step ## Important Notes * **Single Face Limitation**: The 'akool\_faceswap\_image\_hq' model **only supports single face** swapping in an image * For images with **multiple faces**, use the [V3 Image Faceswap API](/ai-tools-suite/faceswap/image-faceswap) * This simplified API does not require the `opts` parameter, making it easier to use compared to V3 * Face enhance must be a boolean value (true/false), default is false * Best suited for high-quality portrait images with clear facial features # Video Faceswap Source: https://docs.akool.com/ai-tools-suite/faceswap/video-faceswap POST /api/open/v3/faceswap/highquality/specifyvideo Swap faces in videos with high quality The resources (image, video, voice) generated by our API are valid for 7 days. Please save the relevant resources as soon as possible to prevent expiration. ## Important Notes * **sourceImage**: You need to change it to the link collection of the face you need. Pass your image through the [Face Detect API](/ai-tools-suite/faceswap/face-detect) to obtain the link and key point data * **targetImage**: Represents the collection of faces after face detection using modifyVideo. When the original video has multiple faces, here is the image link and key point data of each face * When using [Face Detect API](/ai-tools-suite/faceswap/face-detect), set `single_face: true` to return only the largest face data, or `false` to return all detected faces * Ensure that each picture in the sourceImage is a single face, otherwise the face change may fail * You need to ensure that sourceImage and targetImage correspond to each other in order # Image Generate Source: https://docs.akool.com/ai-tools-suite/image-generate Easily create an image from scratch with our AI image generator by entering descriptive text. The resources (image, video, voice) generated by our API are valid for 7 days. Please save the relevant resources as soon as possible to prevent expiration. ### Text to image / Image to image ``` POST https://openapi.akool.com/api/open/v3/content/image/createbyprompt ``` **Request Headers** | **Parameter** | **Value** | **Description** | | ------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | x-api-key | API Key | Your API Key used for request authorization. If both Authorization and x-api-key have values, Authorization will be used first and x-api-key will be discarded. | | Authorization | Bearer `{token}` | Your API Key used for request authorization.[Get Token](/authentication/usage#get-the-token) | **Body Attributes** | **Parameter** | **Type** | **Value** | **Description** | | ------------- | -------- | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | | prompt | String | | Describe the information needed to generate the image | | scale | String | "1:1" "4:3" "3:4" "16:9" "9:16" "3:2" "2:3" | The size of the generated image default: "1:1" | | source\_image | String | | Need to generate the original image link of the image 【If you want to perform imageToImage operation you can pass in this parameter】 | | webhookUrl | String | | Callback url address based on HTTP request | **Response Attributes** | **Parameter** | **Type** | **Value** | **Description** | | ------------- | -------- | ------------------------------ | ------------------------------------------------------------------------------------------------------------------- | | code | int | 1000 | Interface returns business status code(1000:success) | | msg | String | | Interface returns status information | | data | Object | `{ _id: "", image_status: 1 }` | \_id: Interface returns data, image\_status: the status of image: 【1:queueing, 2:processing, 3:completed, 4:failed】 | **Example** **Body** ```json theme={null} { "prompt": "Sun Wukong is surrounded by heavenly soldiers and generals", // Describe the information needed to generate the image "scale": "1:1", "source_image": "https://drz0f01yeq1cx.cloudfront.net/1708333063911-9cbe39b7-3c5f-4a35-894c-359a6cbb76c3-3283.png", // Need to generate the original image link of the image 【If you want to perform imageToImage operation you can pass in this parameter】 "webhookUrl":"" // Callback url address based on HTTP request } ``` **Request** ```bash cURL theme={null} curl --location 'https://openapi.akool.com/api/open/v3/content/image/createbyprompt' \ --header "x-api-key: {{API Key}}" \ --header 'Content-Type: application/json' \ --data '{ "prompt": "Sun Wukong is surrounded by heavenly soldiers and generals", "source_image": "https://drz0f01yeq1cx.cloudfront.net/1708333063911-9cbe39b7-3c5f-4a35-894c-359a6cbb76c3-3283.png", "scale": "1:1", "webhookUrl":"" } ' ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, "{\n \"prompt\": \"Sun Wukong is surrounded by heavenly soldiers and generals\", \n \"source_image\": \"https://drz0f01yeq1cx.cloudfront.net/1708333063911-9cbe39b7-3c5f-4a35-894c-359a6cbb76c3-3283.png\", \n \"webhookUrl\":\"\" \n}\n"); Request request = new Request.Builder() .url("https://openapi.akool.com/api/open/v3/content/image/createbyprompt") .method("POST", body) .addHeader("x-api-key", "{{API Key}}") .addHeader("Content-Type", "application/json") .build(); Response response = client.newCall(request).execute(); ``` ```javascript Javascript theme={null} const myHeaders = new Headers(); myHeaders.append("x-api-key", "{{API Key}}"); myHeaders.append("Content-Type", "application/json"); const raw = JSON.stringify({ "prompt": "Sun Wukong is surrounded by heavenly soldiers and generals", "source_image": "https://drz0f01yeq1cx.cloudfront.net/1708333063911-9cbe39b7-3c5f-4a35-894c-359a6cbb76c3-3283.png", "scale": "1:1", "webhookUrl": "" }); const requestOptions = { method: "POST", headers: myHeaders, body: raw, redirect: "follow" }; fetch("https://openapi.akool.com/api/open/v3/content/image/createbyprompt", requestOptions) .then((response) => response.text()) .then((result) => console.log(result)) .catch((error) => console.error(error)); ``` ```php PHP theme={null} '{{API Key}}', 'Content-Type' => 'application/json' ]; $body = '{ "prompt": "Sun Wukong is surrounded by heavenly soldiers and generals", "source_image": "https://drz0f01yeq1cx.cloudfront.net/1708333063911-9cbe39b7-3c5f-4a35-894c-359a6cbb76c3-3283.png", "scale": "1:1", "webhookUrl": "" }'; $request = new Request('POST', 'https://openapi.akool.com/api/open/v3/content/image/createbyprompt', $headers, $body); $res = $client->sendAsync($request)->wait(); echo $res->getBody(); ``` ```python Python theme={null} import requests import json url = "https://openapi.akool.com/api/open/v3/content/image/createbyprompt" payload = json.dumps({ "prompt": "Sun Wukong is surrounded by heavenly soldiers and generals", "source_image": "https://drz0f01yeq1cx.cloudfront.net/1708333063911-9cbe39b7-3c5f-4a35-894c-359a6cbb76c3-3283.png", "scale": "1:1", "webhookUrl": "" }) headers = { 'x-api-key':'{{API Key}}', 'Content-Type': 'application/json' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text) ``` **Response** ```json theme={null} { "code": 1000, "msg": "OK", "data": { "faceswap_quality": 2, "deduction_credit": 2, "buttons": [], "used_buttons": [], "upscaled_urls": [], "_id": "64dd82eef0b6684651e90131", "uid": 378337, "create_time": 1692238574633, "origin_prompt": "***", "source_image": "https://***.cloudfront.net/1702436829534-4a813e6c-303e-48c7-8a4e-b915ae408b78-5034.png", "prompt": "***** was a revolutionary leader who transformed *** into a powerful communist state.", "type": 4, "from": 1, "image_status": 1 // the status of image: 【1:queueing, 2:processing,3:completed, 4:failed】 } } ``` ### Generate 4K or variations ``` POST https://openapi.akool.com/api/open/v3/content/image/createbybutton ``` **Request Headers** | **Parameter** | **Value** | **Description** | | ------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | x-api-key | API Key | Your API Key used for request authorization. If both Authorization and x-api-key have values, Authorization will be used first and x-api-key will be discarded. | | Authorization | Bearer `{token}` | Your API Key used for request authorization.[Get Token](/authentication/usage#get-the-token) | **Body Attributes** | **Parameter** | **Type** | **Value** | **Description** | | ------------- | -------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | \_id | String | | the image`_id` you had generated, you can got it from [Create By Prompt API](/ai-tools-suite/image-generate#text-to-image-image-to-image) | | button | String | | the type of operation you want to perform, You can get the field(display\_buttons) value from [Info By Model ID API](/ai-tools-suite/image-generate#get-image-result-image-info)【U(1-4): Generate a single 4k image based on the corresponding serial number original image, V(1-4):Generate a single variant image based on the corresponding serial number original image】 | | webhookUrl | String | | Callback url address based on HTTP request | **Response Attributes** | **Parameter** | **Type** | **Value** | **Description** | | ------------- | -------- | ------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | code | int | 1000 | Interface returns business status code(1000:success) | | msg | String | | Interface returns status information | | data | Object | `{_id:"",image_content_model_id: "",op_button: "",image_status:1}` | `_id`: Interface returns data image\_content\_model\_id: the origin image `_id` you had generated op\_button: the type of operation you want to perform image\_status: the status of image: 【1:queueing, 2:processing, 3:completed, 4:failed】 | **Example** **Body** ```json theme={null} { "_id": "65d3206b83ccf5ab7d46cdc6", // the image【_id】 you had generated, you can got it from https://openapi.akool.com/api/open/v3/content/image/createbyprompt "button": "U2", // the type of operation you want to perform, You can get the field(display_buttons) value from https://content.akool.com/api/v1/content/image/infobyid 【U(1-4): Generate a single 4k image based on the corresponding serial number original image, V(1-4):Generate a single variant image based on the corresponding serial number original image】 "webhookUrl":"" // Callback url address based on HTTP request } ``` **Request** ```bash cURL theme={null} curl --location 'https://openapi.akool.com/api/open/v3/content/image/createbybutton' \ --header "x-api-key: {{API Key}}" \ --header 'Content-Type: application/json' \ --data '{ "_id": "65d3206b83ccf5ab7d46cdc6", "button": "U2", "webhookUrl":"" }' ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, "{\n \"_id\": \"65d3206b83ccf5ab7d46cdc6\", \n \"button\": \"U2\", \n \"webhookUrl\":\"\" \n}"); Request request = new Request.Builder() .url("https://openapi.akool.com/api/open/v3/content/image/createbybutton") .method("POST", body) .addHeader("x-api-key", "{{API Key}}") .addHeader("Content-Type", "application/json") .build(); Response response = client.newCall(request).execute(); ``` ```js Javascript theme={null} const myHeaders = new Headers(); myHeaders.append("x-api-key", "{{API Key}}"); myHeaders.append("Content-Type", "application/json"); const raw = JSON.stringify({ "_id": "65d3206b83ccf5ab7d46cdc6", "button": "U2", "webhookUrl": "" }); const requestOptions = { method: "POST", headers: myHeaders, body: raw, redirect: "follow" }; fetch("https://openapi.akool.com/api/open/v3/content/image/createbybutton", requestOptions) .then((response) => response.text()) .then((result) => console.log(result)) .catch((error) => console.error(error)); ``` ```php PHP theme={null} '{{API Key}}', 'Content-Type' => 'application/json' ]; $body = '{ "_id": "65d3206b83ccf5ab7d46cdc6", "button": "U2", "webhookUrl": "" }'; $request = new Request('POST', 'https://openapi.akool.com/api/open/v3/content/image/createbybutton', $headers, $body); $res = $client->sendAsync($request)->wait(); echo $res->getBody(); ``` ```python Python theme={null} import requests import json url = "https://openapi.akool.com/api/open/v3/content/image/createbybutton" payload = json.dumps({ "_id": "65d3206b83ccf5ab7d46cdc6", "button": "U2", "webhookUrl": "" }) headers = { 'x-api-key':'{{API Key}}', 'Content-Type': 'application/json' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text) ``` **Response** ```json theme={null} { "code": 1000, "msg": "OK", "data": { "faceswap_quality": 2, "deduction_credit": 2, "buttons": [], "used_buttons": [], "upscaled_urls": [], "_id": "6508292f16e5ba407d47d21b", "image_content_model_id": "6508288416e5ba407d47d13f", // the origin image【_id】 you had generated "create_time": 1695033647012, "op_button": "U2", // the type of operation you want to perform "op_buttonMessageId": "kwZsk6elltno5Nt37VLj", "image_status": 1, // the status of image: 【1:queueing, 2:processing, 3:completed, 4:failed】 "from": 1 } } ``` ### Get Image Result image info ``` GET https://openapi.akool.com/api/open/v3/content/image/infobymodelid?image_model_id=64dd838cf0b6684651e90217 ``` **Request Headers** | **Parameter** | **Value** | **Description** | | ------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | x-api-key | API Key | Your API Key used for request authorization. If both Authorization and x-api-key have values, Authorization will be used first and x-api-key will be discarded. | | Authorization | Bearer `{token}` | Your API Key used for request authorization.[Get Token](/authentication/usage#get-the-token) | **Query Attributes** | **Parameter** | **Type** | **Value** | **Description** | | ---------------- | -------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | image\_model\_id | String | | image db id:You can get it based on the `_id` field returned by [Create By Prompt API](/ai-tools-suite/image-generate#text-to-image-image-to-image) or [Create By Button API](/ai-tools-suite/image-generate#generate-4k-or-variations) api. | **Response Attributes** | **Parameter** | **Type** | **Value** | **Description** | | ------------- | -------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | | code | int | 1000 | Interface returns business status code(1000:success) | | msg | String | | Interface returns status information | | data | Object | `{image_status:1,_id:"",image:""}` | image\_status: the status of image: 【1:queueing, 2:processing, 3:completed, 4:failed】 image: Image result after processing \_id: Interface returns data | **Example** **Request** ```bash cURL theme={null} curl --location 'https://openapi.akool.com/api/open/v3/content/image/infobymodelid?image_model_id=662a10df4197b3af58532e89' \ --header "x-api-key: {{API Key}}" ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("text/plain"); RequestBody body = RequestBody.create(mediaType, ""); Request request = new Request.Builder() .url("https://openapi.akool.com/api/open/v3/content/image/infobymodelid?image_model_id=662a10df4197b3af58532e89") .method("GET", body) .addHeader("x-api-key", "{{API Key}}") .build(); Response response = client.newCall(request).execute(); ``` ```js Javascript theme={null} const myHeaders = new Headers(); myHeaders.append("x-api-key", "{{API Key}}"); const requestOptions = { method: "GET", headers: myHeaders, redirect: "follow" }; fetch("https://openapi.akool.com/api/open/v3/content/image/infobymodelid?image_model_id=662a10df4197b3af58532e89", requestOptions) .then((response) => response.text()) .then((result) => console.log(result)) .catch((error) => console.error(error)); ``` ```php PHP theme={null} '{{API Key}}' ]; $request = new Request('GET', 'https://openapi.akool.com/api/open/v3/content/image/infobymodelid?image_model_id=662a10df4197b3af58532e89', $headers); $res = $client->sendAsync($request)->wait(); echo $res->getBody(); ``` ```python Python theme={null} import requests url = "https://openapi.akool.com/api/open/v3/content/image/infobymodelid?image_model_id=662a10df4197b3af58532e89" payload = {} headers = { 'x-api-key':'{{API Key}}' } response = requests.request("GET", url, headers=headers, data=payload) print(response.text) ``` **Response** ```json theme={null} { "code": 1000, "msg": "OK", "data": { "faceswap_quality": 2, "deduction_credit": 2, "buttons": [ "U1", "U2", "U3", "U4", "V1", "V2", "V3", "V4"], "used_buttons": [], "upscaled_urls": [], "_id": "662a10df4197b3af58532e89", "create_time": 1714032863272, "uid": 378337, "type": 3, "image_status": 3, // the status of image:【1:queueing, 2:processing,3:completed,4:failed】 "image": "https://***.cloudfront.net/1714032892336-e0ec9305-e217-4b79-8704-e595a822c12b-8013.png" // Image result after processing } } ``` **Response Code Description** Please note that if the value of the response code is not equal to 1000, the request is failed or wrong | **Parameter** | **Value** | **Description** | | ------------- | --------- | ------------------------------------------------------ | | code | 1000 | Success | | code | 1003 | Parameter error or Parameter can not be empty | | code | 1008 | The content you get does not exist | | code | 1009 | You do not have permission to operate | | code | 1010 | You can not operate this content | | code | 1101 | Invalid authorization or The request token has expired | | code | 1102 | Authorization cannot be empty | | code | 1108 | image generate error,please try again later | | code | 1200 | The account has been banned | # Image to Video Source: https://docs.akool.com/ai-tools-suite/image2video Easily transform static images into dynamic videos with our AI Image to Video tool by adding motion, transitions, and effects in seconds. You can use the following APIs to create videos from images with various effects and audio options. The resources (image, video, voice) generated by our API are valid for 7 days. Please save the relevant resources as soon as possible to prevent expiration. Experience our Image to Video AI technology in action by exploring our interactive demo on GitHub: [AKool Image to Video Demo](https://github.com/AKOOL-Official/akool-image-to-video-demo). This demo showcases how to transform static images into dynamic videos using prompt-driven animation, with support for multiple AI models, effects, and audio integration. ## Pricing ### Image to Video | Video Duration | 720p | 1080p | 4k | | -------------- | ---------------- | ---------------- | ---------------- | | 5 seconds | 20 credits/video | 25 credits/video | 30 credits/video | | 10 seconds | 40 credits/video | 50 credits/video | 60 credits/video | ### Video to Audio | Video Duration | Credits | | -------------- | ---------------- | | 5 seconds | 5 credits/video | | 10 seconds | 10 credits/video | **Note:** The Video to Audio feature is charged only when used separately. It is free of charge when included in Image to Video. ## Create Image to Video ``` POST https://openapi.akool.com/api/open/v4/image2Video/createBySourcePrompt ``` **Request Headers** | **Parameter** | **Value** | **Description** | | ------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | x-api-key | API Key | Your API Key used for request authorization. If both Authorization and x-api-key have values, Authorization will be used first and x-api-key will be discarded. | | Authorization | Bearer `{token}` | Your API Key used for request authorization.[Get Token](/authentication/usage#get-the-token) | **Body Attributes** | **Parameter** | **Type** | **Required** | **Description** | | ------------------ | -------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------ | | image\_url | String | true | Image URL to be animated | | prompt | String | true | Prompt text describing how to animate the image | | negative\_prompt | String | true | Prompt text describing what to avoid in the animation | | extend\_prompt | Boolean | false | Whether to use algorithm default extended prompts | | resolution | String | true | Resolution options: 720p, 1080p, 4k | | audio\_url | String | false | Audio URL, required when audio\_type = 2 | | audio\_type | Integer | true | Audio type: 1 = AI generate, 2 = user custom upload, 3 = none (no audio) | | video\_length | Integer | true | Video duration in seconds, options: 5, 10 (10s only available for pro and above subscriptions) | | is\_premium\_model | Boolean | false | Whether to use premium video model for faster generation (pro and above subscriptions only) | | effect\_code | String | false | Effect code: if specified, prompt content will be ignored.[Get Effect Code](/ai-tools-suite/image2video#get-available-effects) | | webhookurl | String | false | Callback URL for POST requests | **Response Attributes** | **Parameter** | **Type** | **Description** | | ------------------- | -------- | ------------------------------------------------------------ | | code | Integer | Interface returns business status code (1000:success) | | msg | String | Interface returns status information | | data | Object | Response data object | | - create\_time | Long | Creation timestamp | | - uid | Integer | User ID | | - team\_id | String | Team ID | | - status | Integer | Task status: 1=queueing, 2=processing, 3=completed, 4=failed | | - webhookUrl | String | Callback URL | | - resolution | String | Video resolution | | - file\_name | String | Output file name | | - effect\_name | String | Effect name | | - \_id | String | Document ID | | - image\_url | String | Input image URL | | - prompt | String | Animation prompt | | - negative\_prompt | String | Negative prompt | | - extend\_prompt | Boolean | Whether extended prompts were used | | - audio\_type | Integer | Audio type used | | - audio\_url | String | Audio URL used | | - deduction\_credit | Integer | Credits deducted | | - effect\_code | String | Effect code used | **Example** **Body** ```json theme={null} { "image_url": "https://drz0f01yeq1cx.cloudfront.net/1753772478686-9524-b6e4169bb1b44d5d8361936b3f6eddb8.png", "prompt": "Animate this image with smooth camera movement and subtle object motion.", "negative_prompt": "blurry, distorted hands, missing fingers, unnatural pose, double hands, extra limbs, bad anatomy, low quality, cartoonish, exaggerated features, open mouth, aggressive expression, modern clothing, pixelated, vibrant colors, overexposed, flickering, blurry details, subtitles, logo, style, artwork, painting, picture, static, overall grayish, worst quality, JPEG compression artifacts, ugly, incomplete, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, malformed limbs, fused fingers, static characters, messy background, three legs, crowded background, walking backwards", "extend_prompt": true, "resolution": "4k", "audio_url": "https://drz0f01yeq1cx.cloudfront.net/1753772497950-9213-1749809724426audio.mp3", "audio_type": 2, "video_length": 10, "is_premium_model": true, "effect_code": "squish_89244231312", "webhookurl": "" } ``` **Request** ```bash cURL theme={null} curl --location 'https://openapi.akool.com/api/open/v4/image2Video/createBySourcePrompt' \ --header 'x-api-key: {{API Key}}' \ --header 'Content-Type: application/json' \ --data '{ "image_url": "https://drz0f01yeq1cx.cloudfront.net/1753772478686-9524-b6e4169bb1b44d5d8361936b3f6eddb8.png", "prompt": "Animate this image with smooth camera movement and subtle object motion.", "negative_prompt": "blurry, distorted hands, missing fingers, unnatural pose, double hands, extra limbs, bad anatomy, low quality, cartoonish, exaggerated features, open mouth, aggressive expression, modern clothing, pixelated, vibrant colors, overexposed, flickering, blurry details, subtitles, logo, style, artwork, painting, picture, static, overall grayish, worst quality, JPEG compression artifacts, ugly, incomplete, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, malformed limbs, fused fingers, static characters, messy background, three legs, crowded background, walking backwards", "extend_prompt": true, "resolution": "4k", "audio_url": "https://drz0f01yeq1cx.cloudfront.net/1753772497950-9213-1749809724426audio.mp3", "audio_type": 2, "video_length": 10, "is_premium_model": true, "effect_code": "squish_89244231312", "webhookurl": "" }' ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, "{\n \"image_url\": \"https://drz0f01yeq1cx.cloudfront.net/1753772478686-9524-b6e4169bb1b44d5d8361936b3f6eddb8.png\",\n \"prompt\": \"Animate this image with smooth camera movement and subtle object motion.\",\n \"negative_prompt\": \"blurry, distorted hands, missing fingers, unnatural pose, double hands, extra limbs, bad anatomy, low quality, cartoonish, exaggerated features, open mouth, aggressive expression, modern clothing, pixelated, vibrant colors, overexposed, flickering, blurry details, subtitles, logo, style, artwork, painting, picture, static, overall grayish, worst quality, JPEG compression artifacts, ugly, incomplete, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, malformed limbs, fused fingers, static characters, messy background, three legs, crowded background, walking backwards\",\n \"extend_prompt\": true,\n \"resolution\": \"4k\",\n \"audio_url\": \"https://drz0f01yeq1cx.cloudfront.net/1753772497950-9213-1749809724426audio.mp3\",\n \"audio_type\": 2,\n \"video_length\": 10,\n \"is_premium_model\": true,\n \"effect_code\": \"squish_89244231312\",\n \"webhookurl\": \"\"\n}"); Request request = new Request.Builder() .url("https://openapi.akool.com/api/open/v4/image2Video/createBySourcePrompt") .method("POST", body) .addHeader("x-api-key", "{{API Key}}") .addHeader("Content-Type", "application/json") .build(); Response response = client.newCall(request).execute(); ``` ```js Javascript theme={null} const myHeaders = new Headers(); myHeaders.append("x-api-key", "{{API Key}}"); myHeaders.append("Content-Type", "application/json"); const raw = JSON.stringify({ "image_url": "https://drz0f01yeq1cx.cloudfront.net/1753772478686-9524-b6e4169bb1b44d5d8361936b3f6eddb8.png", "prompt": "Animate this image with smooth camera movement and subtle object motion.", "negative_prompt": "blurry, distorted hands, missing fingers, unnatural pose, double hands, extra limbs, bad anatomy, low quality, cartoonish, exaggerated features, open mouth, aggressive expression, modern clothing, pixelated, vibrant colors, overexposed, flickering, blurry details, subtitles, logo, style, artwork, painting, picture, static, overall grayish, worst quality, JPEG compression artifacts, ugly, incomplete, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, malformed limbs, fused fingers, static characters, messy background, three legs, crowded background, walking backwards", "extend_prompt": true, "resolution": "4k", "audio_url": "https://drz0f01yeq1cx.cloudfront.net/1753772497950-9213-1749809724426audio.mp3", "audio_type": 2, "video_length": 10, "is_premium_model": true, "effect_code": "squish_89244231312", "webhookurl": "" }); const requestOptions = { method: "POST", headers: myHeaders, body: raw, redirect: "follow" }; fetch("https://openapi.akool.com/api/open/v4/image2Video/createBySourcePrompt", requestOptions) .then((response) => response.text()) .then((result) => console.log(result)) .catch((error) => console.error(error)); ``` ```php PHP theme={null} '{{API Key}}', 'Content-Type' => 'application/json' ]; $body = '{ "image_url": "https://drz0f01yeq1cx.cloudfront.net/1753772478686-9524-b6e4169bb1b44d5d8361936b3f6eddb8.png", "prompt": "Animate this image with smooth camera movement and subtle object motion.", "negative_prompt": "blurry, distorted hands, missing fingers, unnatural pose, double hands, extra limbs, bad anatomy, low quality, cartoonish, exaggerated features, open mouth, aggressive expression, modern clothing, pixelated, vibrant colors, overexposed, flickering, blurry details, subtitles, logo, style, artwork, painting, picture, static, overall grayish, worst quality, JPEG compression artifacts, ugly, incomplete, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, malformed limbs, fused fingers, static characters, messy background, three legs, crowded background, walking backwards", "extend_prompt": true, "resolution": "4k", "audio_url": "https://drz0f01yeq1cx.cloudfront.net/1753772497950-9213-1749809724426audio.mp3", "audio_type": 2, "video_length": 10, "is_premium_model": true, "effect_code": "squish_89244231312", "webhookurl": "" }'; $request = new Request('POST', 'https://openapi.akool.com/api/open/v4/image2Video/createBySourcePrompt', $headers, $body); $res = $client->sendAsync($request)->wait(); echo $res->getBody(); ?> ``` ```python Python theme={null} import requests import json url = "https://openapi.akool.com/api/open/v4/image2Video/createBySourcePrompt" payload = json.dumps({ "image_url": "https://drz0f01yeq1cx.cloudfront.net/1753772478686-9524-b6e4169bb1b44d5d8361936b3f6eddb8.png", "prompt": "Animate this image with smooth camera movement and subtle object motion.", "negative_prompt": "blurry, distorted hands, missing fingers, unnatural pose, double hands, extra limbs, bad anatomy, low quality, cartoonish, exaggerated features, open mouth, aggressive expression, modern clothing, pixelated, vibrant colors, overexposed, flickering, blurry details, subtitles, logo, style, artwork, painting, picture, static, overall grayish, worst quality, JPEG compression artifacts, ugly, incomplete, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, malformed limbs, fused fingers, static characters, messy background, three legs, crowded background, walking backwards", "extend_prompt": true, "resolution": "4k", "audio_url": "https://drz0f01yeq1cx.cloudfront.net/1753772497950-9213-1749809724426audio.mp3", "audio_type": 2, "video_length": 10, "is_premium_model": true, "effect_code": "squish_89244231312", "webhookurl": "" }) headers = { 'x-api-key':'{{API Key}}', 'Content-Type': 'application/json' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text) ``` **Response** ```json theme={null} { "code": 1000, "msg": "OK", "data": { "create_time": 1754362985482, "uid": 101400, "team_id": "6805fb69e92d9edc7ca0b409", "status": 1, "webhookUrl": "", "resolution": "4k", "file_name": "Image2Video_Animate this image with .mp4", "effect_name": "Squish", "_id": "689174694b4dbdd4ab3d28c9", "image_url": "https://drz0f01yeq1cx.cloudfront.net/1753772478686-9524-b6e4169bb1b44d5d8361936b3f6eddb8.png", "prompt": "Animate this image with smooth camera movement and subtle object motion.", "negative_prompt": "blurry, distorted hands, missing fingers, unnatural pose, double hands, extra limbs, bad anatomy, low quality, cartoonish, exaggerated features, open mouth, aggressive expression, modern clothing, pixelated, vibrant colors, overexposed, flickering, blurry details, subtitles, logo, style, artwork, painting, picture, static, overall grayish, worst quality, JPEG compression artifacts, ugly, incomplete, extra fingers, poorly drawn hands, poorly drawn face, deformed, disfigured, malformed limbs, fused fingers, static characters, messy background, three legs, crowded background, walking backwards", "extend_prompt": true, "audio_type": 2, "audio_url": "https://drz0f01yeq1cx.cloudfront.net/1753772497950-9213-1749809724426audio.mp3", "deduction_credit": 60, "effect_code": "squish_89244231312" } } ``` ## Create Batch Image to Video ``` POST https://openapi.akool.com/api/open/v4/image2Video/createBySourcePrompt/batch ``` **Request Headers** | **Parameter** | **Value** | **Description** | | ------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | x-api-key | API Key | Your API Key used for request authorization. If both Authorization and x-api-key have values, Authorization will be used first and x-api-key will be discarded. | | Authorization | Bearer `{token}` | Your API Key used for request authorization.[Get Token](/authentication/usage#get-the-token) | **Body Attributes** | **Parameter** | **Type** | **Required** | **Description** | | ---------------- | -------- | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | image\_url | String | true | Image URL to be animated | | prompt | String | true | Prompt text describing how to animate the image | | model\_name | String | false | AI model name (get available models from [Get AI Model List](/ai-tools-suite/aimodel#get-ai-model-list)) | | negative\_prompt | String | false | Prompt text describing what to avoid in the animation | | extend\_prompt | Boolean | false | Whether to use algorithm default extended prompts | | resolution | String | true | Resolution value (e.g., 720p, 1080p, 4k). Available options are retrieved from the resolutionList field of the selected model in [Get AI Model List](/ai-tools-suite/aimodel#get-ai-model-list) | | video\_length | Integer | true | Video duration in seconds. Available durations are retrieved from the durationList field of the selected model in [Get AI Model List](/ai-tools-suite/aimodel#get-ai-model-list) | | last\_image\_url | String | false | URL of the image to use as the last frame of the video | | count | Integer | false | Number of videos to create simultaneously (1-10), default: 1 | | webhookurl | String | false | Callback URL for POST requests | **Response Attributes** | **Parameter** | **Type** | **Description** | | ------------- | -------- | ----------------------------------------------------- | | code | Integer | Interface returns business status code (1000:success) | | msg | String | Interface returns status information | | data | Object | Response data object | | - successList | Array | Array of successfully created video tasks | | - errorList | Array | Array of failed tasks with error information | **successList Item Attributes** | **Parameter** | **Type** | **Description** | | ----------------- | -------- | ------------------------------------------------------------ | | \_id | String | Document ID | | create\_time | Long | Creation timestamp | | uid | Integer | User ID | | team\_id | String | Team ID | | status | Integer | Task status: 1=queueing, 2=processing, 3=completed, 4=failed | | webhookUrl | String | Callback URL | | resolution | String | Video resolution | | file\_name | String | Output file name | | effect\_name | String | Effect name | | image\_url | String | Input image URL | | prompt | String | Animation prompt | | negative\_prompt | String | Negative prompt | | extend\_prompt | Boolean | Whether extended prompts were used | | last\_image\_url | String | Last frame image URL | | deduction\_credit | Integer | Credits deducted | | model\_name | String | AI model name used | | batch\_id | String | Batch ID for grouping videos created in the same request | | batch\_count | Integer | Total number of videos in this batch | **Example** **Body** ```json theme={null} { "image_url": "https://drz0f01yeq1cx.cloudfront.net/1753772478686-9524-b6e4169bb1b44d5d8361936b3f6eddb8.png", "prompt": "Animate this image with smooth camera movement and subtle object motion.", "model_name": "seedance-1-0-lite-i2v-250428", "negative_prompt": "blurry, distorted, low quality", "extend_prompt": true, "resolution": "720p", "video_length": 5, "last_image_url": "https://drz0f01yeq1cx.cloudfront.net/1753772478686-9524-last-frame.png", "count": 3 } ``` **Request** ```bash cURL theme={null} curl --location 'https://openapi.akool.com/api/open/v4/image2Video/createBySourcePrompt/batch' \ --header 'x-api-key: {{API Key}}' \ --header 'Content-Type: application/json' \ --data '{ "image_url": "https://drz0f01yeq1cx.cloudfront.net/1753772478686-9524-b6e4169bb1b44d5d8361936b3f6eddb8.png", "prompt": "Animate this image with smooth camera movement and subtle object motion.", "model_name": "seedance-1-0-lite-i2v-250428", "negative_prompt": "blurry, distorted, low quality", "extend_prompt": true, "resolution": "720p", "video_length": 5, "last_image_url": "https://drz0f01yeq1cx.cloudfront.net/1753772478686-9524-last-frame.png", "count": 3 }' ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, "{\n \"image_url\": \"https://drz0f01yeq1cx.cloudfront.net/1753772478686-9524-b6e4169bb1b44d5d8361936b3f6eddb8.png\",\n \"prompt\": \"Animate this image with smooth camera movement and subtle object motion.\",\n \"model_name\": \"seedance-1-0-lite-i2v-250428\",\n \"negative_prompt\": \"blurry, distorted, low quality\",\n \"extend_prompt\": true,\n \"resolution\": \"720p\",\n \"video_length\": 5,\n \"last_image_url\": \"https://drz0f01yeq1cx.cloudfront.net/1753772478686-9524-last-frame.png\",\n \"count\": 3\n}"); Request request = new Request.Builder() .url("https://openapi.akool.com/api/open/v4/image2Video/createBySourcePrompt/batch") .method("POST", body) .addHeader("x-api-key", "{{API Key}}") .addHeader("Content-Type", "application/json") .build(); Response response = client.newCall(request).execute(); ``` ```js Javascript theme={null} const myHeaders = new Headers(); myHeaders.append("x-api-key", "{{API Key}}"); myHeaders.append("Content-Type", "application/json"); const raw = JSON.stringify({ "image_url": "https://drz0f01yeq1cx.cloudfront.net/1753772478686-9524-b6e4169bb1b44d5d8361936b3f6eddb8.png", "prompt": "Animate this image with smooth camera movement and subtle object motion.", "model_name": "seedance-1-0-lite-i2v-250428", "negative_prompt": "blurry, distorted, low quality", "extend_prompt": true, "resolution": "720p", "video_length": 5, "last_image_url": "https://drz0f01yeq1cx.cloudfront.net/1753772478686-9524-last-frame.png", "count": 3 }); const requestOptions = { method: "POST", headers: myHeaders, body: raw, redirect: "follow" }; fetch("https://openapi.akool.com/api/open/v4/image2Video/createBySourcePrompt/batch", requestOptions) .then((response) => response.text()) .then((result) => console.log(result)) .catch((error) => console.error(error)); ``` ```php PHP theme={null} '{{API Key}}', 'Content-Type' => 'application/json' ]; $body = '{ "image_url": "https://drz0f01yeq1cx.cloudfront.net/1753772478686-9524-b6e4169bb1b44d5d8361936b3f6eddb8.png", "prompt": "Animate this image with smooth camera movement and subtle object motion.", "model_name": "seedance-1-0-lite-i2v-250428", "negative_prompt": "blurry, distorted, low quality", "extend_prompt": true, "resolution": "720p", "video_length": 5, "last_image_url": "https://drz0f01yeq1cx.cloudfront.net/1753772478686-9524-last-frame.png", "count": 3 }'; $request = new Request('POST', 'https://openapi.akool.com/api/open/v4/image2Video/createBySourcePrompt/batch', $headers, $body); $res = $client->sendAsync($request)->wait(); echo $res->getBody(); ?> ``` ```python Python theme={null} import requests import json url = "https://openapi.akool.com/api/open/v4/image2Video/createBySourcePrompt/batch" payload = json.dumps({ "image_url": "https://drz0f01yeq1cx.cloudfront.net/1753772478686-9524-b6e4169bb1b44d5d8361936b3f6eddb8.png", "prompt": "Animate this image with smooth camera movement and subtle object motion.", "model_name": "seedance-1-0-lite-i2v-250428", "negative_prompt": "blurry, distorted, low quality", "extend_prompt": True, "resolution": "720p", "video_length": 5, "last_image_url": "https://drz0f01yeq1cx.cloudfront.net/1753772478686-9524-last-frame.png", "count": 3 }) headers = { 'x-api-key':'{{API Key}}', 'Content-Type': 'application/json' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text) ``` **Response** ```json theme={null} { "code": 1000, "msg": "OK", "data": { "successList": [ { "_id": "689174694b4dbdd4ab3d28c9", "create_time": 1754362985482, "uid": 101400, "team_id": "6805fb69e92d9edc7ca0b409", "status": 1, "webhookUrl": "", "resolution": "720p", "file_name": "Image2Video_Animate this image with .mp4", "image_url": "https://drz0f01yeq1cx.cloudfront.net/1753772478686-9524-b6e4169bb1b44d5d8361936b3f6eddb8.png", "prompt": "Animate this image with smooth camera movement and subtle object motion.", "negative_prompt": "blurry, distorted, low quality", "extend_prompt": true, "deduction_credit": 5, "model_name": "seedance-1-0-lite-i2v-250428", "batch_id": "1754362985482_101400", "batch_count": 3 }, { "_id": "689174694b4dbdd4ab3d28ca", "create_time": 1754362985483, "uid": 101400, "team_id": "6805fb69e92d9edc7ca0b409", "status": 1, "webhookUrl": "", "resolution": "720p", "file_name": "Image2Video_Animate this image with .mp4", "image_url": "https://drz0f01yeq1cx.cloudfront.net/1753772478686-9524-b6e4169bb1b44d5d8361936b3f6eddb8.png", "prompt": "Animate this image with smooth camera movement and subtle object motion.", "negative_prompt": "blurry, distorted, low quality", "extend_prompt": true, "deduction_credit": 5, "model_name": "seedance-1-0-lite-i2v-250428", "batch_id": "1754362985482_101400", "batch_count": 3 }, { "_id": "689174694b4dbdd4ab3d28cb", "create_time": 1754362985484, "uid": 101400, "team_id": "6805fb69e92d9edc7ca0b409", "status": 1, "webhookUrl": "", "resolution": "720p", "file_name": "Image2Video_Animate this image with .mp4", "image_url": "https://drz0f01yeq1cx.cloudfront.net/1753772478686-9524-b6e4169bb1b44d5d8361936b3f6eddb8.png", "prompt": "Animate this image with smooth camera movement and subtle object motion.", "negative_prompt": "blurry, distorted, low quality", "extend_prompt": true, "deduction_credit": 5, "model_name": "seedance-1-0-lite-i2v-250428", "batch_id": "1754362985482_101400", "batch_count": 3 } ], "errorList": [] } } ``` **Integration Workflow** 1. **Get Available Models** ``` GET /api/open/v4/aigModel/list?types[]=1501 ``` 2. **User Selects Model and Parameters** * Display models from step 1 * Show supported resolutions and durations * Calculate and display credit cost 3. **Create Video(s)** ``` POST /api/open/v4/image2Video/createBySourcePrompt/batch ``` With selected `model_name` and parameters 4. **Check Results** ``` POST /api/open/v4/image2Video/resultsByIds ``` Using the `_id` values from creation response **Notes** * Models are sorted by `sort` field in descending order (higher values first) * The `value` field should be used as the `model_name` parameter in creation APIs * Resolution pricing may vary by model; check `resolutionList` for accurate costs * Some advanced models may require paid accounts (`requiresPay: true`) * The API returns an empty array for model types that are not yet implemented ## Get Image to Video Results ``` POST https://openapi.akool.com/api/open/v4/image2Video/resultsByIds ``` **Request Headers** | **Parameter** | **Value** | **Description** | | ------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | x-api-key | API Key | Your API Key used for request authorization. If both Authorization and x-api-key have values, Authorization will be used first and x-api-key will be discarded. | | Authorization | Bearer `{token}` | Your API Key used for request authorization.[Get Token](/authentication/usage#get-the-token) | **Body Attributes** | **Parameter** | **Type** | **Required** | **Description** | | ------------- | -------- | ------------ | -------------------------------- | | \_ids | String | true | Multiple IDs separated by commas | **Response Attributes** | **Parameter** | **Type** | **Description** | | -------------------- | -------- | ------------------------------------------------------- | | code | Integer | Interface returns business status code (1000:success) | | msg | String | Interface returns status information | | data | Object | Response data object | | - result | Array | Array of result objects | | -- \_id | String | Document ID | | -- create\_time | Long | Creation timestamp | | -- uid | Integer | User ID | | -- team\_id | String | Team ID | | -- update\_time | Long | Last update time/completion time | | -- video\_duration | Number | Actual video duration | | -- webhookUrl | String | Callback URL | | -- file\_name | String | File name | | -- effect\_name | String | Effect name | | -- image\_url | String | Image URL | | -- prompt | String | Prompt text | | -- resolution | String | Resolution | | -- audio\_type | Integer | Audio type | | -- audio\_url | String | Audio URL | | -- deduction\_credit | Integer | Actual credits deducted | | -- effect\_code | String | Effect code | | -- video\_url | String | Generated video URL | | -- status | Integer | Status: 1=queueing, 2=processing, 3=completed, 4=failed | | -- only\_add\_audio | Boolean | Whether only audio was added | **Example** **Body** ```json theme={null} { "_ids": "68919a464b4dbdd4ab3d3034,6891a07f5d612f78c9204f1c" } ``` **Request** ```bash cURL theme={null} curl --location 'https://openapi.akool.com/api/open/v4/image2Video/resultsByIds' \ --header 'x-api-key: {{API Key}}' \ --header 'Content-Type: application/json' \ --data '{ "_ids": "68919a464b4dbdd4ab3d3034,6891a07f5d612f78c9204f1c" }' ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, "{\n \"_ids\": \"68919a464b4dbdd4ab3d3034,6891a07f5d612f78c9204f1c\"\n}"); Request request = new Request.Builder() .url("https://openapi.akool.com/api/open/v4/image2Video/resultsByIds") .method("POST", body) .addHeader("x-api-key", "{{API Key}}") .addHeader("Content-Type", "application/json") .build(); Response response = client.newCall(request).execute(); ``` ```js Javascript theme={null} const myHeaders = new Headers(); myHeaders.append("x-api-key", "{{API Key}}"); myHeaders.append("Content-Type", "application/json"); const raw = JSON.stringify({ "_ids": "68919a464b4dbdd4ab3d3034,6891a07f5d612f78c9204f1c" }); const requestOptions = { method: "POST", headers: myHeaders, body: raw, redirect: "follow" }; fetch("https://openapi.akool.com/api/open/v4/image2Video/resultsByIds", requestOptions) .then((response) => response.text()) .then((result) => console.log(result)) .catch((error) => console.error(error)); ``` ```php PHP theme={null} '{{API Key}}', 'Content-Type' => 'application/json' ]; $body = '{ "_ids": "68919a464b4dbdd4ab3d3034,6891a07f5d612f78c9204f1c" }'; $request = new Request('POST', 'https://openapi.akool.com/api/open/v4/image2Video/resultsByIds', $headers, $body); $res = $client->sendAsync($request)->wait(); echo $res->getBody(); ?> ``` ```python Python theme={null} import requests import json url = "https://openapi.akool.com/api/open/v4/image2Video/resultsByIds" payload = json.dumps({ "_ids": "68919a464b4dbdd4ab3d3034,6891a07f5d612f78c9204f1c" }) headers = { 'x-api-key':'{{API Key}}', 'Content-Type': 'application/json' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text) ``` **Response** ```json theme={null} { "code": 1000, "msg": "OK", "data": { "result": [ { "_id": "6891a2295d612f78c9204f77", "create_time": 1754374697629, "uid": 101400, "team_id": "6805fb69e92d9edc7ca0b409", "update_time": 1754374394023, "video_duration": 5.063, "webhookUrl": "", "file_name": "Image2Video_Animate this image with .mp4", "effect_name": "Squish", "image_url": "https://drz0f01yeq1cx.cloudfront.net/1753772478686-9524-b6e4169bb1b44d5d8361936b3f6eddb8.png", "prompt": "Animate this image with smooth camera movement and subtle object motion.", "resolution": "4k", "audio_type": 2, "audio_url": "https://drz0f01yeq1cx.cloudfront.net/1753772497950-9213-1749809724426audio.mp3", "deduction_credit": 5, "effect_code": "squish_89244231312", "status": 1, "only_add_audio": true }, { "_id": "6891abe782f7cd2a890c44ba", "create_time": 1754377191100, "uid": 101400, "team_id": "6805fb69e92d9edc7ca0b409", "sub_type": 1501, "video_duration": 5.063, "webhookUrl": "", "file_name": "Image2Video_Animate this image with .mp4", "effect_name": "Squish", "update_time": 1754377293090, "image_url": "https://drz0f01yeq1cx.cloudfront.net/1753772478686-9524-b6e4169bb1b44d5d8361936b3f6eddb8.png", "prompt": "Animate this image with smooth camera movement and subtle object motion.", "resolution": "4k", "audio_type": 2, "audio_url": "https://drz0f01yeq1cx.cloudfront.net/1753772497950-9213-1749809724426audio.mp3", "deduction_credit": 30, "effect_code": "squish_89244231312", "video_url": "https://d2qf6ukcym4kn9.cloudfront.net/1754377291791-1423.mp4", "status": 3, "only_add_audio": false } ] } } ``` ## Get Available Effects ``` GET https://openapi.akool.com/api/open/v4/image2Video/effects ``` **Request Headers** | **Parameter** | **Value** | **Description** | | ------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | x-api-key | API Key | Your API Key used for request authorization. If both Authorization and x-api-key have values, Authorization will be used first and x-api-key will be discarded. | | Authorization | Bearer `{token}` | Your API Key used for request authorization.[Get Token](/authentication/usage#get-the-token) | **Response Attributes** | **Parameter** | **Type** | **Description** | | --------------- | -------- | ----------------------------------------------------- | | code | Integer | Interface returns business status code (1000:success) | | msg | String | Interface returns status information | | data | Object | Response data object | | - result | Array | Array of effect objects | | -- \_id | String | Effect document ID | | -- create\_time | Long | Creation timestamp | | -- logo | String | Effect logo URL | | -- name | String | Effect name | | -- video\_url | String | Effect preview video URL | | -- effect\_code | String | Effect code | | - count | Integer | Total number of effects | **Request** ```bash cURL theme={null} curl --location 'https://openapi.akool.com/api/open/v4/image2Video/effects' \ --header 'x-api-key: {{API Key}}' ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); Request request = new Request.Builder() .url("https://openapi.akool.com/api/open/v4/image2Video/effects") .method("GET", null) .addHeader("x-api-key", "{{API Key}}") .build(); Response response = client.newCall(request).execute(); ``` ```js Javascript theme={null} const myHeaders = new Headers(); myHeaders.append("x-api-key", "{{API Key}}"); const requestOptions = { method: "GET", headers: myHeaders, redirect: "follow" }; fetch("https://openapi.akool.com/api/open/v4/image2Video/effects", requestOptions) .then((response) => response.text()) .then((result) => console.log(result)) .catch((error) => console.error(error)); ``` ```php PHP theme={null} '{{API Key}}' ]; $request = new Request('GET', 'https://openapi.akool.com/api/open/v4/image2Video/effects', $headers); $res = $client->sendAsync($request)->wait(); echo $res->getBody(); ?> ``` ```python Python theme={null} import requests url = "https://openapi.akool.com/api/open/v4/image2Video/effects" headers = { 'x-api-key':'{{API Key}}' } response = requests.request("GET", url, headers=headers) print(response.text) ``` **Response** ```json theme={null} { "code": 1000, "msg": "Success", "data": { "result": [ { "_id": "687632b95a0f52799eeed701", "create_time": 1752576694502, "logo": "https://static.website-files.org/assets/Image_to_Video/Lora/Squish.png", "name": "Squish", "video_url": "https://static.website-files.org/assets/Image_to_Video/Lora/Squish.mp4", "effect_code": "squish_89244231312" }, { "_id": "687632ba5a0f52799eeed887", "create_time": 1752576694502, "logo": "https://static.website-files.org/assets/Image_to_Video/Lora/Cakeify.png", "name": "Cakeify", "video_url": "https://static.website-files.org/assets/Image_to_Video/Lora/Cakeify.mp4", "effect_code": "cakeify_24743216" }, { "_id": "687632bc5a0f52799eeed929", "create_time": 1752576694502, "logo": "https://static.website-files.org/assets/Image_to_Video/Lora/Samurai.png", "name": "Samurai", "video_url": "https://static.website-files.org/assets/Image_to_Video/Lora/Samurai.mp4", "effect_code": "samurai_99757865" } ], "count": 10 } } ``` ## Update Video Audio ``` POST https://openapi.akool.com/api/open/v4/image2Video/updateVideoAudio ``` **Request Headers** | **Parameter** | **Value** | **Description** | | ------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | x-api-key | API Key | Your API Key used for request authorization. If both Authorization and x-api-key have values, Authorization will be used first and x-api-key will be discarded. | | Authorization | Bearer `{token}` | Your API Key used for request authorization.[Get Token](/authentication/usage#get-the-token) | **Body Attributes** | **Parameter** | **Type** | **Required** | **Description** | | -------------- | -------- | ------------ | ---------------------------------------- | | pre\_video\_id | String | true | Image to Video result \_id | | audio\_url | String | true | Audio URL, required when audio\_type = 2 | | audio\_type | Integer | true | 1 = AI Generate, 2 = user custom upload | **Response Attributes** | **Parameter** | **Type** | **Description** | | ------------------- | -------- | ------------------------------------------------------- | | code | Integer | Interface returns business status code (1000:success) | | msg | String | Interface returns status information | | data | Object | Response data object | | - create\_time | Long | Creation timestamp | | - uid | Integer | User ID | | - team\_id | String | Team ID | | - update\_time | Long | Last update time | | - video\_duration | Number | Video duration | | - webhookUrl | String | Callback URL | | - resolution | String | Resolution | | - file\_name | String | File name | | - effect\_name | String | Effect name | | - \_id | String | Document ID | | - pre\_video\_id | String | Original video ID | | - image\_url | String | Image URL | | - prompt | String | Prompt text | | - negative\_prompt | String | Negative prompt | | - extend\_prompt | Boolean | Whether extended prompts were used | | - audio\_type | Integer | Audio type | | - audio\_url | String | Audio URL | | - deduction\_credit | Integer | Credits deducted | | - effect\_code | String | Effect code | | - status | Integer | Status: 1=queueing, 2=processing, 3=completed, 4=failed | | - only\_add\_audio | Boolean | Whether only audio was added | **Example** **Body** ```json theme={null} { "pre_video_id": "6890830af27dfad2a3e6062d", "audio_url": "https://drz0f01yeq1cx.cloudfront.net/1753772497950-9213-1749809724426audio.mp3", "audio_type": 2 } ``` **Request** ```bash cURL theme={null} curl --location 'https://openapi.akool.com/api/open/v4/image2Video/updateVideoAudio' \ --header 'x-api-key: {{API Key}}' \ --header 'Content-Type: application/json' \ --data '{ "pre_video_id": "6890830af27dfad2a3e6062d", "audio_url": "https://drz0f01yeq1cx.cloudfront.net/1753772497950-9213-1749809724426audio.mp3", "audio_type": 2 }' ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, "{\n \"pre_video_id\": \"6890830af27dfad2a3e6062d\",\n \"audio_url\": \"https://drz0f01yeq1cx.cloudfront.net/1753772497950-9213-1749809724426audio.mp3\",\n \"audio_type\": 2\n}"); Request request = new Request.Builder() .url("https://openapi.akool.com/api/open/v4/image2Video/updateVideoAudio") .method("POST", body) .addHeader("x-api-key", "{{API Key}}") .addHeader("Content-Type", "application/json") .build(); Response response = client.newCall(request).execute(); ``` ```js Javascript theme={null} const myHeaders = new Headers(); myHeaders.append("x-api-key", "{{API Key}}"); myHeaders.append("Content-Type", "application/json"); const raw = JSON.stringify({ "pre_video_id": "6890830af27dfad2a3e6062d", "audio_url": "https://drz0f01yeq1cx.cloudfront.net/1753772497950-9213-1749809724426audio.mp3", "audio_type": 2 }); const requestOptions = { method: "POST", headers: myHeaders, body: raw, redirect: "follow" }; fetch("https://openapi.akool.com/api/open/v4/image2Video/updateVideoAudio", requestOptions) .then((response) => response.text()) .then((result) => console.log(result)) .catch((error) => console.error(error)); ``` ```php PHP theme={null} '{{API Key}}', 'Content-Type' => 'application/json' ]; $body = '{ "pre_video_id": "6890830af27dfad2a3e6062d", "audio_url": "https://drz0f01yeq1cx.cloudfront.net/1753772497950-9213-1749809724426audio.mp3", "audio_type": 2 }'; $request = new Request('POST', 'https://openapi.akool.com/api/open/v4/image2Video/updateVideoAudio', $headers, $body); $res = $client->sendAsync($request)->wait(); echo $res->getBody(); ?> ``` ```python Python theme={null} import requests import json url = "https://openapi.akool.com/api/open/v4/image2Video/updateVideoAudio" payload = json.dumps({ "pre_video_id": "6890830af27dfad2a3e6062d", "audio_url": "https://drz0f01yeq1cx.cloudfront.net/1753772497950-9213-1749809724426audio.mp3", "audio_type": 2 }) headers = { 'x-api-key':'{{API Key}}', 'Content-Type': 'application/json' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text) ``` **Response** ```json theme={null} { "code": 1000, "msg": "OK", "data": { "create_time": 1754374697629, "uid": 101400, "team_id": "6805fb69e92d9edc7ca0b409", "update_time": 1754374394023, "video_duration": 5.063, "webhookUrl": "", "resolution": "4k", "file_name": "Image2Video_Animate this image with .mp4", "effect_name": "Squish", "_id": "6891a2295d612f78c9204f77", "pre_video_id": "6891a07f5d612f78c9204f1c", "image_url": "https://drz0f01yeq1cx.cloudfront.net/1753772478686-9524-b6e4169bb1b44d5d8361936b3f6eddb8.png", "prompt": "Animate this image with smooth camera movement and subtle object motion.", "negative_prompt": "", "extend_prompt": false, "audio_type": 2, "audio_url": "https://drz0f01yeq1cx.cloudfront.net/1753772497950-9213-1749809724426audio.mp3", "deduction_credit": 5, "effect_code": "squish_89244231312", "status": 1, "only_add_audio": true } } ``` ## Delete Videos ``` POST https://openapi.akool.com/api/open/v4/image2Video/delbyids ``` **Request Headers** | **Parameter** | **Value** | **Description** | | ------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | x-api-key | API Key | Your API Key used for request authorization. If both Authorization and x-api-key have values, Authorization will be used first and x-api-key will be discarded. | | Authorization | Bearer `{token}` | Your API Key used for request authorization.[Get Token](/authentication/usage#get-the-token) | **Body Attributes** | **Parameter** | **Type** | **Required** | **Description** | | ------------- | -------- | ------------ | -------------------------------- | | \_ids | String | true | Multiple IDs separated by commas | **Response Attributes** | **Parameter** | **Type** | **Description** | | ------------------- | -------- | ----------------------------------------------------- | | code | Integer | Interface returns business status code (1000:success) | | msg | String | Interface returns status information | | data | Object | Response data object | | - successIds | Array | Successfully deleted video IDs | | - noPermissionItems | Array | Failed deletion information list | | -- \_id | String | Failed deletion video ID | | -- msg | String | Failure reason | **Example** **Body** ```json theme={null} { "_ids": "68919a464b4dbdd4ab3d3034,6891a07f5d612f78c9204f1c,6891a2295d612f78c9204f77" } ``` **Request** ```bash cURL theme={null} curl --location 'https://openapi.akool.com/api/open/v4/image2Video/delbyids' \ --header 'x-api-key: {{API Key}}' \ --header 'Content-Type: application/json' \ --data '{ "_ids": "68919a464b4dbdd4ab3d3034,6891a07f5d612f78c9204f1c,6891a2295d612f78c9204f77" }' ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, "{\n \"_ids\": \"68919a464b4dbdd4ab3d3034,6891a07f5d612f78c9204f1c,6891a2295d612f78c9204f77\"\n}"); Request request = new Request.Builder() .url("https://openapi.akool.com/api/open/v4/image2Video/delbyids") .method("POST", body) .addHeader("x-api-key", "{{API Key}}") .addHeader("Content-Type", "application/json") .build(); Response response = client.newCall(request).execute(); ``` ```js Javascript theme={null} const myHeaders = new Headers(); myHeaders.append("x-api-key", "{{API Key}}"); myHeaders.append("Content-Type", "application/json"); const raw = JSON.stringify({ "_ids": "68919a464b4dbdd4ab3d3034,6891a07f5d612f78c9204f1c,6891a2295d612f78c9204f77" }); const requestOptions = { method: "POST", headers: myHeaders, body: raw, redirect: "follow" }; fetch("https://openapi.akool.com/api/open/v4/image2Video/delbyids", requestOptions) .then((response) => response.text()) .then((result) => console.log(result)) .catch((error) => console.error(error)); ``` ```php PHP theme={null} '{{API Key}}', 'Content-Type' => 'application/json' ]; $body = '{ "_ids": "68919a464b4dbdd4ab3d3034,6891a07f5d612f78c9204f1c,6891a2295d612f78c9204f77" }'; $request = new Request('POST', 'https://openapi.akool.com/api/open/v4/image2Video/delbyids', $headers, $body); $res = $client->sendAsync($request)->wait(); echo $res->getBody(); ?> ``` ```python Python theme={null} import requests import json url = "https://openapi.akool.com/api/open/v4/image2Video/delbyids" payload = json.dumps({ "_ids": "68919a464b4dbdd4ab3d3034,6891a07f5d612f78c9204f1c,6891a2295d612f78c9204f77" }) headers = { 'x-api-key':'{{API Key}}', 'Content-Type': 'application/json' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text) ``` **Response** ```json theme={null} { "code": 1000, "msg": "Delete successfully", "data": { "successIds": [ "6882f4c10529ae771e71531d" ], "noPermissionItems": [ { "_id": "6881cd86618fa41c89557b0c", "msg": "video resource is processing, please try again later" } ] } } ``` # Jarvis Moderator Source: https://docs.akool.com/ai-tools-suite/jarvis-moderator # Overview Automate content moderation reduces the cost of your image, video, text, and voice moderation by accurately detecting inappropriate content. Jarvis Moderator provides services through open application programming interfaces (APIs). You can obtain the inference result by calling APIs. It helps you build an intelligent service system and improves service efficiency. * A software tool such as curl and Postman These are good options if you are more comfortable writing code, HTTP requests, and API calls. For details, see Using Postman to Call Jarvis. # Internationalization labels The following content will be subject to review and detection to ensure compliance with relevant laws, regulations, and platform policies: 1. Advertising: Detects malicious advertising and redirection content to prevent users from being led to unsafe or inappropriate sites. 2. Violent Content: Detects violent or terrorist content to prevent the dissemination of harmful information. 3. Political Content: Reviews political content to ensure that it does not involve sensitive or inflammatory political information. 4. Specified Speech: Detects specified speech or voice content to identify and manage audio that meets certain conditions. 5. Specified Lyrics: Detects specified lyrics content to prevent the spread of inappropriate or harmful lyrics. 6. Sexual Content: Reviews content related to sexual behavior or sexual innuendo to protect users from inappropriate information. 7. Moaning Sounds: Detects sounds related to sexual activity, such as moaning, to prevent the spread of such audio. 8. Contraband: Identifies and blocks all illegal or prohibited content. 9. Profane Language: Reviews and filters content containing profanity or vulgar language. 10. Religious Content: Reviews religious content to avoid controversy or offense to specific religious beliefs. 11. Cyberbullying: Detects cyberbullying behavior to prevent such content from harming users. 12. Harmful or Inappropriate Content: Reviews and manages harmful or inappropriate content to maintain a safe and positive environment on the platform. 13. Silent Audio: Detects silent audio content to identify and address potential technical issues or other anomalies. 14. Customized Content: Allows users to define and review specific types of content according to business needs or compliance requirements. This content will be thoroughly detected by our review system to ensure that all content on the platform meets the relevant standards and regulations. # Subscribing to the Service **NOTE:** This service is available only to enterprise users now. To subscribe to Jarvis Moderator, perform the following steps: 1. Register an AKOOL account. 2. Then click the picture icon in the upper right corner of the website, and click the “APl Credentials” function to set the key pair (clientId, clientSecret) used when accessing the API and save it. 3. Use the secret key pair just saved to send the api interface to obtain the access token. 4. Pricing: | **Content Type** | **Credits** | **Pricing** | | ---------------- | ------------------- | ----------------------- | | Text | 0.1C/600 characters | 0.004USD/600 characters | | Image | 0.2C/image | 0.008USD/image | | Audio | 0.5C/min | 0.02USD/min | | Video | 1C/min | 0.04USD/min | ### Jarvis Moderator ``` POST https://openapi.akool.com/api/open/v3/content/analysis/sentiment ``` **Request Headers** | **Parameter** | **Value** | **Description** | | ------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | x-api-key | API Key | Your API Key used for request authorization. If both Authorization and x-api-key have values, Authorization will be used first and x-api-key will be discarded. | | Authorization | Bearer `{token}` | Your API Key used for request authorization.[Get Token](/authentication/usage#get-the-token). | **Body Attributes** | **Parameter** | **Type** | **Value** | **Description** | | ------------- | -------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | | content | String | | url or text, when the content is a image, video, or audio, a url must be provided. When the content provided is text, it can be either text content or a url. | | type | Number | | 1: image 2:video 3: auido 4: text | | language | String | | When type=2 or 3 or 4, it is best to provide the language to ensure the accuracy of the results。 Supplying the input language in ISO-639-1 format | | webhookUrl | String | | Callback url address based on HTTP request. | | input | String | Optional | The user defines the content to be detected in words | We restrict image to 20MB. we currently support PNG (.png), JPEG (.jpeg and .jpg), WEBP (.webp), and non-animated GIF (.gif). We restrict audio to 25MB, 60minute. we currently support .flac, .mp3, .mp4, .mpeg, .mpga, .m4a, .ogg, .wav, .webm We restrict video to 1024MB, resolution limited to 1080p. we currently support .mp4, .avi When the content provided is text, it can be either text content or a url. If it is url, we currently support .txt, .docx, .xml, .pdf, .csv, .md, .json ISO-639-1: [https://en.wikipedia.org/wiki/List\_of\_ISO\_639\_language\_codes](https://en.wikipedia.org/wiki/List_of_ISO_639_language_codes) **Response Attributes** | **Parameter** | **Type** | **Value** | **Description** | | ------------- | -------- | ---------------------------- | -------------------------------------------------------------------------------------------------------------- | | code | int | 1000 | Interface returns business status code(1000:success) | | msg | String | | Interface returns status information | | data | Object | `{ "_id": "", "status": 1 }` | `_id`: Interface returns data, status: the status of video: \[1:queueing, 2:processing, 3:completed, 4:failed] | **Example** **Body** ```json theme={null} { "type":1, // 1:image 2:video 3: auido 4:text "content":"https://drz0f01yeq1cx.cloudfront.net/1714023431475-food.jpg", "webhookUrl":"" } ``` **Request** ```bash cURL theme={null} curl --location 'https://openapi.akool.com/api/open/v3/content/analysis/sentiment' \ --header "x-api-key: {{API Key}}" \ --header 'Content-Type: application/json' \ --data '{ "type":1, "content":"https://drz0f01yeq1cx.cloudfront.net/1714023431475-food.jpg", }' ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, "{\n \n \"type\":1,\n \"content\":\"https://drz0f01yeq1cx.cloudfront.net/1714023431475-food.jpg\"\n\n}"); Request request = new Request.Builder() .url("https://openapi.akool.com/api/open/v3/content/analysis/sentiment") .method("POST", body) .addHeader("x-api-key", "{{API Key}}") .addHeader("Content-Type", "application/json") .build(); Response response = client.newCall(request).execute(); ``` ```js Javascript theme={null} const myHeaders = new Headers(); myHeaders.append("x-api-key", "{{API Key}}"); myHeaders.append("Content-Type", "application/json"); const raw = JSON.stringify({ "type": 1, "content": "https://drz0f01yeq1cx.cloudfront.net/1714023431475-food.jpg" }); const requestOptions = { method: "POST", headers: myHeaders, body: raw, redirect: "follow" }; fetch("https://openapi.akool.com/api/open/v3/content/analysis/sentiment", requestOptions) .then((response) => response.text()) .then((result) => console.log(result)) .catch((error) => console.error(error)); ``` ```php PHP theme={null} '{{API Key}}', 'Content-Type' => 'application/json' ]; $body = '{ "type": 1, "content": "https://drz0f01yeq1cx.cloudfront.net/1714023431475-food.jpg" }'; $request = new Request('POST', 'https://openapi.akool.com/api/open/v3/content/analysis/sentiment', $headers, $body); $res = $client->sendAsync($request)->wait(); echo $res->getBody(); ``` ```python Python theme={null} import requests import json url = "https://openapi.akool.com/api/open/v3/content/analysis/sentiment" payload = json.dumps({ "type": 1, "content": "https://drz0f01yeq1cx.cloudfront.net/1714023431475-food.jpg" }) headers = { 'x-api-key':'{{API Key}}', 'Content-Type': 'application/json' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text) ``` **Response** ```json theme={null} { "code": 1000, "msg": "OK", "data": { "create_time": 1710757900382, "uid": 101690, "type": 1, "status": 1, // current status of content: 【1:queueing(The requested operation is being processed),2:processing(The requested operation is being processing),3:completed(The request operation has been processed successfully),4:failed(The request operation processing failed)】 "webhookUrl": "", "result": "", "_id": "65f8180c24d9989e93dde3b6", "__v": 0 } } ``` ### Get analysis Info Result ``` GET https://openapi.akool.com/api/open/v3/content/analysis/infobyid?_id=662df7928ee006bf033b64bf ``` **Request Headers** | **Parameter** | **Value** | **Description** | | ------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | x-api-key | API Key | Your API Key used for request authorization. If both Authorization and x-api-key have values, Authorization will be used first and x-api-key will be discarded. | | Authorization | Bearer `{token}` | Your API Key used for request authorization.[Get Token](/authentication/usage#get-the-token) | **Query Attributes** | **Parameter** | **Type** | **Value** | **Description** | | ------------- | -------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | | \_id | String | NULL | video db id: You can get it based on the `_id` field returned by [Sentiment Analysis API](/ai-tools-suite/jarvis-moderator#jarvis-moderator) . | **Response Attributes** | **Parameter** | **Type** | **Value** | **Description** | | ------------- | -------- | ------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | code | int | 1000 | Interface returns business status code(1000:success) | | msg | String | OK | Interface returns status information | | data | Object | `{ status:1, _id:"", result:"", final_conclusion: "" }` | video\_status: the status of video:【1:queueing, 2:processing, 3:completed, 4:failed】 result: sentiment analysis result【Related information returned by the detection content】 final\_conclusion: final conclusion.【Non-Compliant、Compliant、Unknown】 \_id: Interface returns data | **Example** **Request** ```bash cURL theme={null} curl --location 'https://openapi.akool.com/api/open/v3/content/analysis/infobyid?_id=662e20b93baa7aa53169a325' \ --header "x-api-key: {{API Key}}" ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("text/plain"); RequestBody body = RequestBody.create(mediaType, ""); Request request = new Request.Builder() .url("https://openapi.akool.com/api/open/v3/content/analysis/infobyid?_id=662e20b93baa7aa53169a325") .method("GET", body) .addHeader("x-api-key", "{{API Key}}") .build(); Response response = client.newCall(request).execute(); ``` ```js Javascript theme={null} const myHeaders = new Headers(); myHeaders.append("x-api-key", "{{API Key}}"); const requestOptions = { method: "GET", headers: myHeaders, redirect: "follow" }; fetch("https://openapi.akool.com/api/open/v3/content/analysis/infobyid?_id=662e20b93baa7aa53169a325", requestOptions) .then((response) => response.text()) .then((result) => console.log(result)) .catch((error) => console.error(error)); ``` ```php PHP theme={null} '{{API Key}}' ]; $request = new Request('GET', 'https://openapi.akool.com/api/open/v3/content/analysis/infobyid?_id=662e20b93baa7aa53169a325', $headers); $res = $client->sendAsync($request)->wait(); echo $res->getBody(); ``` ```python Python theme={null} import requests url = "https://openapi.akool.com/api/open/v3/content/analysis/infobyid?_id=662e20b93baa7aa53169a325" payload = {} headers = { 'x-api-key':'{{API Key}}' } response = requests.request("GET", url, headers=headers, data=payload) print(response.text) ``` **Response** ```json theme={null} { "code": 1000, "msg": "OK", "data": { "_id": "662e20b93baa7aa53169a325", "uid": 100002, "status": 3, "result": "- violence: Presence of a person holding a handgun, which can be associated with violent content.\nResult: Non-Compliant", "final_conclusion" :"Non-Compliant" // Non-Compliant、Compliant、Unknown } } ``` **Response Code Description** Please note that if the value of the response code is not equal to 1000, the request is failed or wrong | **Parameter** | **Value** | **Description** | | ------------- | --------- | ---------------------------------------------------------------------------------- | | code | 1000 | Success | | code | 1003 | Parameter error or Parameter can not be empty | | code | 1008 | The content you get does not exist | | code | 1009 | You do not have permission to operate | | code | 1101 | Invalid authorization or The request token has expired | | code | 1102 | Authorization cannot be empty | | code | 1200 | The account has been banned | | code | 1201 | create audio error, please try again later | | code | 1202 | The same video cannot be translated lipSync in the same language more than 1 times | | code | 1203 | video should be with audio | # Knowledge Base Source: https://docs.akool.com/ai-tools-suite/knowledge-base Create and manage knowledge bases with documents and URLs to enhance Streaming Avatar AI responses, providing contextual information for more accurate and relevant interactions Knowledge bases provide contextual information for Streaming Avatar AI responses. Documents and URLs are processed to enhance the avatar's understanding and response quality during interactive sessions. This API allows you to create and manage knowledge bases that can be integrated with [Streaming Avatar sessions](/ai-tools-suite/live-avatar#create-session) to provide more accurate and contextually relevant AI responses. ## Overview The Knowledge Base API is specifically designed to enhance Streaming Avatar interactions by providing contextual information. You can create and manage knowledge bases containing documents and URLs that give your Streaming Avatar the context needed to provide more accurate, relevant, and intelligent responses during real-time conversations. ### Data Model **Knowledge Base Object:** * `_id`: Knowledge base unique identifier (string) * `team_id`: Team identifier (string, required) * `uid`: User identifier (number) * `user_type`: User type (number, 1=internal user, 2=external user) * `from`: Source type (number, 1=system, 2=user) * `name`: Knowledge base name (string, optional, max 100 characters) * `prologue`: Opening message/greeting text (string, optional, max 2000 characters) - can be used with TTS repeat mode for personalized AI assistant introductions. Set to empty string to clear the prologue * `prompt`: AI prompt instructions (string, optional, max 10,000 characters) * `docs`: Array of document objects (array, optional) * `urls`: Array of URL strings (array, optional) * `create_time`: Creation timestamp (number) * `update_time`: Last update timestamp (number) **Document Object Structure:** ```json theme={null} { "name": "document_name.pdf", "url": "https://example.com/document.pdf", "size": 1024000 } ``` ### File Constraints **Document Limitations:** * **Single file size limit:** 100MB (104,857,600 bytes) * **Total files size limit:** 500MB (524,288,000 bytes) * **Supported formats:** PDF, DOC, DOCX, TXT, MD, JSON, XML, CSV **Field Limitations:** * **name:** Maximum 100 characters * **prologue:** Maximum 2000 characters (recommended for TTS voice synthesis) * **prompt:** Maximum 10,000 characters ## API Endpoints ### List Knowledge Bases Retrieve a paginated list of knowledge bases. ```http theme={null} GET https://openapi.akool.com/api/open/v4/knowledge/list ``` **Request Headers** | **Parameter** | **Value** | **Description** | | ------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | x-api-key | API Key | Your API Key used for request authorization. If both Authorization and x-api-key have values, Authorization will be used first and x-api-key will be discarded. | | Authorization | Bearer `{token}` | Your API Key used for request authorization.[Get Token](/authentication/usage#get-the-token). | **Query Parameters** | **Parameter** | **Type** | **Required** | **Default** | **Description** | | ------------- | -------- | ------------ | ----------- | ----------------------------- | | page | Number | No | 1 | Page number, minimum 1 | | size | Number | No | 10 | Items per page, range 1-100 | | name | String | No | - | Filter by knowledge base name | | from | Number | No | 2 | Filter by source type | **Response Attributes** | **Parameter** | **Type** | **Description** | | ------------- | -------- | ------------------------------------------------------ | | code | Integer | Interface returns business status code (1000: success) | | msg | String | Interface returns status information | | data | Array | Array of knowledge base objects | **Example** **Request** ```bash cURL theme={null} curl --location 'https://openapi.akool.com/api/open/v4/knowledge/list?page=1&size=10' \ --header 'x-api-key: {{API Key}}' ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); Request request = new Request.Builder() .url("https://openapi.akool.com/api/open/v4/knowledge/list?page=1&size=10") .method("GET", null) .addHeader("x-api-key", "{{API Key}}") .build(); Response response = client.newCall(request).execute(); ``` ```js Javascript theme={null} const myHeaders = new Headers(); myHeaders.append("x-api-key", "{{API Key}}"); const requestOptions = { method: "GET", headers: myHeaders, redirect: "follow" }; fetch("https://openapi.akool.com/api/open/v4/knowledge/list?page=1&size=10", requestOptions) .then((response) => response.text()) .then((result) => console.log(result)) .catch((error) => console.error(error)); ``` ```php PHP theme={null} '{{API Key}}' ]; $request = new Request('GET', 'https://openapi.akool.com/api/open/v4/knowledge/list?page=1&size=10', $headers); $res = $client->sendAsync($request)->wait(); echo $res->getBody(); ``` ```python Python theme={null} import requests url = "https://openapi.akool.com/api/open/v4/knowledge/list?page=1&size=10" headers = { 'x-api-key':'{{API Key}}' } response = requests.request("GET", url, headers=headers) print(response.text) ``` **Response** ```json theme={null} { "code": 1000, "msg": "OK", "data": [ { "_id": "64f8a1b2c3d4e5f6a7b8c9d0", "uid": 123, "name": "Customer Support KB", "prompt": "You are a helpful customer support assistant.", "docs": [ { "name": "user_manual.pdf", "url": "https://example.com/user_manual.pdf", "size": 1024000 } ], "urls": [ "https://example.com/help", "https://example.com/faq" ], "create_time": 1640995200000, "update_time": 1640995200000 } ] } ``` ### Create Knowledge Base Create a new knowledge base with optional documents and URLs. ```http theme={null} POST https://openapi.akool.com/api/open/v4/knowledge/create ``` **Request Headers** | **Parameter** | **Value** | **Description** | | ------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | x-api-key | API Key | Your API Key used for request authorization. If both Authorization and x-api-key have values, Authorization will be used first and x-api-key will be discarded. | | Authorization | Bearer `{token}` | Your API Key used for request authorization.[Get Token](/authentication/usage#get-the-token). | **Body Attributes** | **Parameter** | **Type** | **Required** | **Description** | | ------------- | -------- | ------------ | ---------------------------------------------------------------------------------------------------------------------------- | | name | String | No | Knowledge base name, max 100 characters | | prologue | String | No | Opening message/greeting text, max 2000 characters (recommended for TTS playback). Set to empty string to clear the prologue | | prompt | String | No | AI instructions, max 10,000 characters | | docs | Array | No | Array of document objects | | urls | Array | No | Array of URL strings | **Response Attributes** | **Parameter** | **Type** | **Description** | | ------------- | -------- | ------------------------------------------------------ | | code | Integer | Interface returns business status code (1000: success) | | msg | String | Interface returns status information | | data | Object | Created knowledge base object | **Example** **Body** ```json theme={null} { "name": "Customer Support KB", "prologue": "Hello, I'm your AI assistant. How can I help you?", "prompt": "You are a professional AI assistant. Please answer questions based on the provided documents.", "docs": [ { "name": "user_manual.pdf", "url": "https://example.com/user_manual.pdf", "size": 1024000 } ], "urls": [ "https://example.com/help", "https://example.com/faq" ] } ``` **Request** ```bash cURL theme={null} curl --location 'https://openapi.akool.com/api/open/v4/knowledge/create' \ --header 'x-api-key: {{API Key}}' \ --header 'Content-Type: application/json' \ --data '{ "name": "Customer Support KB", "prologue": "Hello, I am your AI assistant. How can I help you?", "prompt": "You are a professional AI assistant. Please answer questions based on the provided documents.", "docs": [ { "name": "user_manual.pdf", "url": "https://example.com/user_manual.pdf", "size": 1024000 } ], "urls": [ "https://example.com/help", "https://example.com/faq" ] }' ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, "{\n \"name\": \"Customer Support KB\",\n \"prologue\": \"Hello, I am your AI assistant. How can I help you?\",\n \"prompt\": \"You are a professional AI assistant. Please answer questions based on the provided documents.\",\n \"docs\": [\n {\n \"name\": \"user_manual.pdf\",\n \"url\": \"https://example.com/user_manual.pdf\",\n \"size\": 1024000\n }\n ],\n \"urls\": [\n \"https://example.com/help\",\n \"https://example.com/faq\"\n ]\n}"); Request request = new Request.Builder() .url("https://openapi.akool.com/api/open/v4/knowledge/create") .method("POST", body) .addHeader("x-api-key", "{{API Key}}") .addHeader("Content-Type", "application/json") .build(); Response response = client.newCall(request).execute(); ``` ```js Javascript theme={null} const myHeaders = new Headers(); myHeaders.append("x-api-key", "{{API Key}}"); myHeaders.append("Content-Type", "application/json"); const raw = JSON.stringify({ "name": "Customer Support KB", "prologue": "Hello, I am your AI assistant. How can I help you?", "prompt": "You are a professional AI assistant. Please answer questions based on the provided documents.", "docs": [ { "name": "user_manual.pdf", "url": "https://example.com/user_manual.pdf", "size": 1024000 } ], "urls": [ "https://example.com/help", "https://example.com/faq" ] }); const requestOptions = { method: "POST", headers: myHeaders, body: raw, redirect: "follow" }; fetch("https://openapi.akool.com/api/open/v4/knowledge/create", requestOptions) .then((response) => response.text()) .then((result) => console.log(result)) .catch((error) => console.error(error)); ``` ```php PHP theme={null} '{{API Key}}', 'Content-Type' => 'application/json' ]; $body = '{ "name": "Customer Support KB", "prologue": "Hello, I am your AI assistant. How can I help you?", "prompt": "You are a professional AI assistant. Please answer questions based on the provided documents.", "docs": [ { "name": "user_manual.pdf", "url": "https://example.com/user_manual.pdf", "size": 1024000 } ], "urls": [ "https://example.com/help", "https://example.com/faq" ] }'; $request = new Request('POST', 'https://openapi.akool.com/api/open/v4/knowledge/create', $headers, $body); $res = $client->sendAsync($request)->wait(); echo $res->getBody(); ``` ```python Python theme={null} import requests import json url = "https://openapi.akool.com/api/open/v4/knowledge/create" payload = json.dumps({ "name": "Customer Support KB", "prologue": "Hello, I am your AI assistant. How can I help you?", "prompt": "You are a professional AI assistant. Please answer questions based on the provided documents.", "docs": [ { "name": "user_manual.pdf", "url": "https://example.com/user_manual.pdf", "size": 1024000 } ], "urls": [ "https://example.com/help", "https://example.com/faq" ] }) headers = { 'x-api-key':'{{API Key}}', 'Content-Type': 'application/json' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text) ``` **Response** ```json theme={null} { "code": 1000, "msg": "OK", "data": { "_id": "64f8a1b2c3d4e5f6a7b8c9d0", "team_id": "team_123456", "uid": 789, "user_type": 2, "from": 2, "name": "Customer Support KB", "prologue": "Hello, I am your AI assistant. How can I help you?", "prompt": "You are a professional AI assistant. Please answer questions based on the provided documents.", "docs": [ { "name": "user_manual.pdf", "url": "https://example.com/user_manual.pdf", "size": 1024000 } ], "urls": [ "https://example.com/help", "https://example.com/faq" ], "create_time": 1640995200000, "update_time": 1640995200000 } } ``` ### Get Knowledge Base Details Retrieve detailed information about a specific knowledge base. ```http theme={null} GET https://openapi.akool.com/api/open/v4/knowledge/detail ``` **Request Headers** | **Parameter** | **Value** | **Description** | | ------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | x-api-key | API Key | Your API Key used for request authorization. If both Authorization and x-api-key have values, Authorization will be used first and x-api-key will be discarded. | | Authorization | Bearer `{token}` | Your API Key used for request authorization.[Get Token](/authentication/usage#get-the-token). | **Query Parameters** | **Parameter** | **Type** | **Required** | **Description** | | ------------- | -------- | ------------ | ----------------- | | id | String | Yes | Knowledge base ID | **Response Attributes** | **Parameter** | **Type** | **Description** | | ------------- | -------- | ------------------------------------------------------ | | code | Integer | Interface returns business status code (1000: success) | | msg | String | Interface returns status information | | data | Object | Knowledge base object details | **Example** **Request** ```bash cURL theme={null} curl --location 'https://openapi.akool.com/api/open/v4/knowledge/detail?id=64f8a1b2c3d4e5f6a7b8c9d0' \ --header 'x-api-key: {{API Key}}' ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); Request request = new Request.Builder() .url("https://openapi.akool.com/api/open/v4/knowledge/detail?id=64f8a1b2c3d4e5f6a7b8c9d0") .method("GET", null) .addHeader("x-api-key", "{{API Key}}") .build(); Response response = client.newCall(request).execute(); ``` ```js Javascript theme={null} const myHeaders = new Headers(); myHeaders.append("x-api-key", "{{API Key}}"); const requestOptions = { method: "GET", headers: myHeaders, redirect: "follow" }; fetch("https://openapi.akool.com/api/open/v4/knowledge/detail?id=64f8a1b2c3d4e5f6a7b8c9d0", requestOptions) .then((response) => response.text()) .then((result) => console.log(result)) .catch((error) => console.error(error)); ``` ```php PHP theme={null} '{{API Key}}' ]; $request = new Request('GET', 'https://openapi.akool.com/api/open/v4/knowledge/detail?id=64f8a1b2c3d4e5f6a7b8c9d0', $headers); $res = $client->sendAsync($request)->wait(); echo $res->getBody(); ``` ```python Python theme={null} import requests url = "https://openapi.akool.com/api/open/v4/knowledge/detail?id=64f8a1b2c3d4e5f6a7b8c9d0" headers = { 'x-api-key':'{{API Key}}' } response = requests.request("GET", url, headers=headers) print(response.text) ``` **Response** ```json theme={null} { "code": 1000, "msg": "OK", "data": { "_id": "64f8a1b2c3d4e5f6a7b8c9d0", "team_id": "team_123456", "uid": 789, "name": "Customer Support KB", "prompt": "You are a professional AI assistant.", "docs": [ { "name": "user_manual.pdf", "url": "https://example.com/user_manual.pdf", "size": 1024000 } ], "urls": [ "https://example.com/help" ], "create_time": 1640995200000, "update_time": 1640995200000 } } ``` ### Update Knowledge Base Update an existing knowledge base by ID. ```http theme={null} POST https://openapi.akool.com/api/open/v4/knowledge/update ``` **Request Headers** | **Parameter** | **Value** | **Description** | | ------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | x-api-key | API Key | Your API Key used for request authorization. If both Authorization and x-api-key have values, Authorization will be used first and x-api-key will be discarded. | | Authorization | Bearer `{token}` | Your API Key used for request authorization.[Get Token](/authentication/usage#get-the-token). | **Body Attributes** | **Parameter** | **Type** | **Required** | **Description** | | ------------- | -------- | ------------ | ----------------------------------------------------------------------------------------------------- | | id | String | Yes | Knowledge base ID to update | | name | String | No | Updated name, max 100 characters | | prologue | String | No | Updated opening message/greeting text, max 2000 characters. Set to empty string to clear the prologue | | prompt | String | No | Updated AI instructions, max 10,000 characters | | docs | Array | No | Updated document array | | urls | Array | No | Updated URL array | **Response Attributes** | **Parameter** | **Type** | **Description** | | ------------- | -------- | ------------------------------------------------------ | | code | Integer | Interface returns business status code (1000: success) | | msg | String | Interface returns status information | | data | Object | Updated knowledge base object | **Example** **Body** ```json theme={null} { "id": "64f8a1b2c3d4e5f6a7b8c9d0", "name": "Updated Customer Support KB", "prologue": "Updated opening message", "prompt": "Updated AI instructions", "docs": [ { "name": "updated_manual.pdf", "url": "https://example.com/updated_manual.pdf", "size": 2048000 } ], "urls": [ "https://example.com/updated-help" ] } ``` **Request** ```bash cURL theme={null} curl --location 'https://openapi.akool.com/api/open/v4/knowledge/update' \ --header 'x-api-key: {{API Key}}' \ --header 'Content-Type: application/json' \ --data '{ "id": "64f8a1b2c3d4e5f6a7b8c9d0", "name": "Updated Customer Support KB", "prologue": "Updated opening message", "prompt": "Updated AI instructions", "docs": [ { "name": "updated_manual.pdf", "url": "https://example.com/updated_manual.pdf", "size": 2048000 } ], "urls": [ "https://example.com/updated-help" ] }' ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, "{\n \"id\": \"64f8a1b2c3d4e5f6a7b8c9d0\",\n \"name\": \"Updated Customer Support KB\",\n \"prologue\": \"Updated opening message\",\n \"prompt\": \"Updated AI instructions\",\n \"docs\": [\n {\n \"name\": \"updated_manual.pdf\",\n \"url\": \"https://example.com/updated_manual.pdf\",\n \"size\": 2048000\n }\n ],\n \"urls\": [\n \"https://example.com/updated-help\"\n ]\n}"); Request request = new Request.Builder() .url("https://openapi.akool.com/api/open/v4/knowledge/update") .method("POST", body) .addHeader("x-api-key", "{{API Key}}") .addHeader("Content-Type", "application/json") .build(); Response response = client.newCall(request).execute(); ``` ```js Javascript theme={null} const myHeaders = new Headers(); myHeaders.append("x-api-key", "{{API Key}}"); myHeaders.append("Content-Type", "application/json"); const raw = JSON.stringify({ "id": "64f8a1b2c3d4e5f6a7b8c9d0", "name": "Updated Customer Support KB", "prologue": "Updated opening message", "prompt": "Updated AI instructions", "docs": [ { "name": "updated_manual.pdf", "url": "https://example.com/updated_manual.pdf", "size": 2048000 } ], "urls": [ "https://example.com/updated-help" ] }); const requestOptions = { method: "POST", headers: myHeaders, body: raw, redirect: "follow" }; fetch("https://openapi.akool.com/api/open/v4/knowledge/update", requestOptions) .then((response) => response.text()) .then((result) => console.log(result)) .catch((error) => console.error(error)); ``` ```php PHP theme={null} '{{API Key}}', 'Content-Type' => 'application/json' ]; $body = '{ "id": "64f8a1b2c3d4e5f6a7b8c9d0", "name": "Updated Customer Support KB", "prologue": "Updated opening message", "prompt": "Updated AI instructions", "docs": [ { "name": "updated_manual.pdf", "url": "https://example.com/updated_manual.pdf", "size": 2048000 } ], "urls": [ "https://example.com/updated-help" ] }'; $request = new Request('POST', 'https://openapi.akool.com/api/open/v4/knowledge/update', $headers, $body); $res = $client->sendAsync($request)->wait(); echo $res->getBody(); ``` ```python Python theme={null} import requests import json url = "https://openapi.akool.com/api/open/v4/knowledge/update" payload = json.dumps({ "id": "64f8a1b2c3d4e5f6a7b8c9d0", "name": "Updated Customer Support KB", "prologue": "Updated opening message", "prompt": "Updated AI instructions", "docs": [ { "name": "updated_manual.pdf", "url": "https://example.com/updated_manual.pdf", "size": 2048000 } ], "urls": [ "https://example.com/updated-help" ] }) headers = { 'x-api-key':'{{API Key}}', 'Content-Type': 'application/json' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text) ``` **Response** ```json theme={null} { "code": 1000, "msg": "OK", "data": { "_id": "64f8a1b2c3d4e5f6a7b8c9d0", "team_id": "team_123456", "uid": 789, "name": "Updated Customer Support KB", "prompt": "Updated AI instructions", "docs": [ { "name": "updated_manual.pdf", "url": "https://example.com/updated_manual.pdf", "size": 2048000 } ], "urls": [ "https://example.com/updated-help" ], "create_time": 1640995200000, "update_time": 1640995300000 } } ``` ### Delete Knowledge Base Delete a knowledge base by ID. ```http theme={null} DELETE https://openapi.akool.com/api/open/v4/knowledge/delete ``` **Request Headers** | **Parameter** | **Value** | **Description** | | ------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | x-api-key | API Key | Your API Key used for request authorization. If both Authorization and x-api-key have values, Authorization will be used first and x-api-key will be discarded. | | Authorization | Bearer `{token}` | Your API Key used for request authorization.[Get Token](/authentication/usage#get-the-token). | **Body Attributes** | **Parameter** | **Type** | **Required** | **Description** | | ------------- | -------- | ------------ | --------------------------- | | id | String | Yes | Knowledge base ID to delete | **Response Attributes** | **Parameter** | **Type** | **Description** | | ------------- | -------- | ------------------------------------------------------ | | code | Integer | Interface returns business status code (1000: success) | | msg | String | Interface returns status information | **Example** **Body** ```json theme={null} { "id": "64f8a1b2c3d4e5f6a7b8c9d0" } ``` **Request** ```bash cURL theme={null} curl --location --request DELETE 'https://openapi.akool.com/api/open/v4/knowledge/delete' \ --header 'x-api-key: {{API Key}}' \ --header 'Content-Type: application/json' \ --data '{ "id": "64f8a1b2c3d4e5f6a7b8c9d0" }' ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, "{\n \"id\": \"64f8a1b2c3d4e5f6a7b8c9d0\"\n}"); Request request = new Request.Builder() .url("https://openapi.akool.com/api/open/v4/knowledge/delete") .method("DELETE", body) .addHeader("x-api-key", "{{API Key}}") .addHeader("Content-Type", "application/json") .build(); Response response = client.newCall(request).execute(); ``` ```js Javascript theme={null} const myHeaders = new Headers(); myHeaders.append("x-api-key", "{{API Key}}"); myHeaders.append("Content-Type", "application/json"); const raw = JSON.stringify({ "id": "64f8a1b2c3d4e5f6a7b8c9d0" }); const requestOptions = { method: "DELETE", headers: myHeaders, body: raw, redirect: "follow" }; fetch("https://openapi.akool.com/api/open/v4/knowledge/delete", requestOptions) .then((response) => response.text()) .then((result) => console.log(result)) .catch((error) => console.error(error)); ``` ```php PHP theme={null} '{{API Key}}', 'Content-Type' => 'application/json' ]; $body = '{ "id": "64f8a1b2c3d4e5f6a7b8c9d0" }'; $request = new Request('DELETE', 'https://openapi.akool.com/api/open/v4/knowledge/delete', $headers, $body); $res = $client->sendAsync($request)->wait(); echo $res->getBody(); ``` ```python Python theme={null} import requests import json url = "https://openapi.akool.com/api/open/v4/knowledge/delete" payload = json.dumps({ "id": "64f8a1b2c3d4e5f6a7b8c9d0" }) headers = { 'x-api-key':'{{API Key}}', 'Content-Type': 'application/json' } response = requests.request("DELETE", url, headers=headers, data=payload) print(response.text) ``` **Response** ```json theme={null} { "code": 1000, "msg": "OK" } ``` ## Integration with Streaming Avatar ### Using Knowledge Base in Streaming Avatar Sessions To enhance your Streaming Avatar with contextual knowledge, simply provide the `knowledge_id` parameter when creating a Streaming Avatar session. This enables the AI to access documents and URLs from your knowledge base, resulting in more informed and accurate responses during real-time interactions. **Reference:** [Create Streaming Avatar Session](/ai-tools-suite/live-avatar#create-streaming-avatar-session) **Example Integration:** ```json theme={null} { "avatar_id": "avatar_123", "background_url": "https://example.com/background.jpg", "duration": 600, "stream_type": "agora", "knowledge_id": "64f8a1b2c3d4e5f6a7b8c9d0" } ``` When a `knowledge_id` is provided, the system automatically: * Incorporates the knowledge base's prompt into the AI's context * Processes documents and URLs to enhance AI understanding * Uses the prologue for personalized AI assistant introductions (if TTS repeat mode is enabled) The prologue field is particularly useful for TTS (Text-to-Speech) models in repeat mode, providing personalized AI assistant introductions at the beginning of LiveAvatar sessions. ## Error Codes | **Code** | **Description** | | -------- | -------------------------- | | 1000 | Success | | 1003 | Parameter validation error | | 1232 | Knowledge not found | | 1233 | Knowledge already exists | | 1234 | Knowledge creation error | | 1235 | Knowledge update error | | 1236 | Knowledge detail error | ## Complete Workflow Example Here's a complete workflow showing how to create a knowledge base and integrate it with your Streaming Avatar for enhanced AI responses: ```bash theme={null} # 1. Create a knowledge base curl -X POST "https://openapi.akool.com/api/open/v4/knowledge/create" \ -H "x-api-key: {{API Key}}" \ -H "Content-Type: application/json" \ -d '{ "name": "Customer Support KB", "prologue": "Hello, I am your customer support assistant. How can I help you today?", "prompt": "You are a helpful customer support assistant. Use the provided documents to answer questions accurately.", "docs": [ { "name": "user_guide.pdf", "url": "https://example.com/user_guide.pdf", "size": 1024000 } ], "urls": [ "https://example.com/help", "https://example.com/faq" ] }' # 2. Use the knowledge base in a streaming avatar session curl -X POST "https://openapi.akool.com/api/open/v4/liveAvatar/session/create" \ -H "x-api-key: {{API Key}}" \ -H "Content-Type: application/json" \ -d '{ "avatar_id": "your_avatar_id", "knowledge_id": "KNOWLEDGE_ID_FROM_STEP_1" }' ``` * Document size can be obtained using JavaScript's `File.size` property for client-side file uploads * Knowledge base names must be unique within a team for the same user * Results are sorted by creation time in descending order * Users can only access knowledge bases within their team # LipSync Source: https://docs.akool.com/ai-tools-suite/lip-sync The resources (image, video, voice) generated by our API are valid for 7 days. Please save the relevant resources as soon as possible to prevent expiration. ### Create lipSync ``` POST https://openapi.akool.com/api/open/v3/content/video/lipsync ``` **Request Headers** | **Parameter** | **Value** | **Description** | | ------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | x-api-key | API Key | Your API Key used for request authorization. If both Authorization and x-api-key have values, Authorization will be used first and x-api-key will be discarded. | | Authorization | Bearer `{token}` | Your API Key used for request authorization.[Get Token](/authentication/usage#get-the-token). | **Body Attributes** | **Parameter** | **Type** | **Value** | **Description** | | ------------- | -------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | | video\_url | String | | The video url address you want to lipsync, fps greater than 25 will affect the generated effect. It is recommended that the video fps be below 25. | | audio\_url | String | | resource address of the audio,It is recommended that the audio length and video length be consistent, otherwise it will affect the generation effect. | | webhookUrl | String | | Callback url address based on HTTP request. | **Response Attributes** | **Parameter** | **Type** | **Value** | **Description** | | ------------- | -------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | | code | int | 1000 | Interface returns business status code(1000:success) | | msg | String | | Interface returns status information | | data | Object | `{ "_id": "", "video_status": 1, "video": "" }` | `id`: Interface returns data, video\_status: the status of video: \[1:queueing, 2:processing, 3:completed, 4:failed], video: the url of Generated video | **Example** **Body** ```json theme={null} { "video_url": "https://d11fbe263bhqij.cloudfront.net/agicontent/video/global_reach/Global_reach_EN_01.mp4", "audio_url": "https://drz0f01yeq1cx.cloudfront.net/1712719410293-driving_audio_2.wav", "webhookUrl": "" } ``` **Request** ```bash cURL theme={null} curl --location 'https://openapi.akool.com/api/open/v3/content/video/lipsync' \ --header "x-api-key: {{API Key}}" \ --header 'content-type: application/json' \ --data '{ "video_url": "https://d11fbe263bhqij.cloudfront.net/agicontent/video/global_reach/Global_reach_EN_01.mp4", "audio_url": "https://drz0f01yeq1cx.cloudfront.net/1712719410293-driving_audio_2.wav", "webhookUrl":"" }' ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, "{\n \"video_url\": \"https://d11fbe263bhqij.cloudfront.net/agicontent/video/global_reach/Global_reach_EN_01.mp4\",\n \"audio_url\": \"https://drz0f01yeq1cx.cloudfront.net/1712719410293-driving_audio_2.wav\",\n \"webhookUrl\":\"\"\n}"); Request request = new Request.Builder() .url("https://openapi.akool.com/api/open/v3/content/video/lipsync") .method("POST", body) .addHeader("x-api-key", "{{API Key}}") .addHeader("content-type", "application/json") .build(); Response response = client.newCall(request).execute(); ``` ```js Javascript theme={null} const myHeaders = new Headers(); myHeaders.append("x-api-key", "{{API Key}}"); myHeaders.append("content-type", "application/json"); const raw = JSON.stringify({ video_url: "https://d11fbe263bhqij.cloudfront.net/agicontent/video/global_reach/Global_reach_EN_01.mp4", audio_url: "https://drz0f01yeq1cx.cloudfront.net/1712719410293-driving_audio_2.wav", webhookUrl: "", }); const requestOptions = { method: "POST", headers: myHeaders, body: raw, redirect: "follow", }; fetch( "https://openapi.akool.com/api/open/v3/content/video/lipsync", requestOptions ) .then((response) => response.text()) .then((result) => console.log(result)) .catch((error) => console.error(error)); ``` ```php PHP theme={null} '{{API Key}}', 'content-type' => 'application/json' ]; $body = '{ "video_url": "https://d11fbe263bhqij.cloudfront.net/agicontent/video/global_reach/Global_reach_EN_01.mp4", "audio_url": "https://drz0f01yeq1cx.cloudfront.net/1712719410293-driving_audio_2.wav", "webhookUrl": "" }'; $request = new Request('POST', 'https://openapi.akool.com/api/open/v3/content/video/lipsync', $headers, $body); $res = $client->sendAsync($request)->wait(); echo $res->getBody(); ``` ```python Python theme={null} import requests import json url = "https://openapi.akool.com/api/open/v3/content/video/lipsync" payload = json.dumps({ "video_url": "https://d11fbe263bhqij.cloudfront.net/agicontent/video/global_reach/Global_reach_EN_01.mp4", "audio_url": "https://drz0f01yeq1cx.cloudfront.net/1712719410293-driving_audio_2.wav", "webhookUrl": "" }) headers = { 'x-api-key':'{{API Key}}', 'content-type': 'application/json' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text) ``` **Response** ```json theme={null} { "code": 1000, "msg": "OK", "data": { "create_time": 1712720702523, "uid": 100002, "type": 9, "from": 2, "target_video": "https://d11fbe263bhqij.cloudfront.net/agicontent/video/global_reach/Global_reach_EN_01.mp4", "faceswap_quality": 2, "video_id": "8ddc4a27-d173-4cf5-aa37-13e340fed8f3", "video_status": 1, // current status of video: 【1:queueing(The requested operation is being processed),2:processing(The requested operation is being processing),3:completed(The request operation has been processed successfully),4:failed(The request operation processing failed, the reason for the failure can be viewed in the video translation details.)】 "video_lock_duration": 11.7, "deduction_lock_duration": 20, "external_video": "", "video": "", // the url of Generated video "storage_loc": 1, "input_audio": "https://drz0f01yeq1cx.cloudfront.net/1712719410293-driving_audio_2.wav", "webhookUrl": "", "task_id": "66160b3ee3ef778679dfd30f", "lipsync": true, "_id": "66160f989dfc997ac289037b", "__v": 0 } } ``` ### Get Video Info Result ``` GET https://openapi.akool.com/api/open/v3/content/video/infobymodelid?video_model_id=66160f989dfc997ac289037b ``` **Request Headers** | **Parameter** | **Value** | **Description** | | ------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | x-api-key | API Key | Your API Key used for request authorization. If both Authorization and x-api-key have values, Authorization will be used first and x-api-key will be discarded. | | Authorization | Bearer `{token}` | Your API Key used for request authorization.[Get Token](/authentication/usage#get-the-token). | **Query Attributes** | **Parameter** | **Type** | **Value** | **Description** | | ---------------- | -------- | --------- | ------------------------------------------------------------------------------------------------------------------------ | | video\_model\_id | String | NULL | video db id: You can get it based on the `_id` field returned by [Lip Sync API](/ai-tools-suite/lip-sync#create-lipsync) | **Response Attributes** | **Parameter** | **Type** | **Value** | **Description** | | ------------- | -------- | -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | | code | int | 1000 | Interface returns business status code(1000:success) | | msg | String | OK | Interface returns status information | | data | Object | `{ video_status:1, _id:"", video:"" }` | video\_status: the status of video:【1:queueing, 2:processing, 3:completed, 4:failed】 video: Generated video resource url \_id: Interface returns data | **Example** **Request** ```bash cURL theme={null} curl --location 'http://openapi.akool.com/api/open/v3/content/video/infobymodelid?video_model_id=66160f989dfc997ac289037b' \ --header "x-api-key: {{API Key}}" ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("text/plain"); RequestBody body = RequestBody.create(mediaType, ""); Request request = new Request.Builder() .url("http://openapi.akool.com/api/open/v3/content/video/infobymodelid?video_model_id=66160f989dfc997ac289037b") .method("GET", body) .addHeader("x-api-key", "{{API Key}}") .build(); Response response = client.newCall(request).execute(); ``` ```js Javascript theme={null} const myHeaders = new Headers(); myHeaders.append("x-api-key", "{{API Key}}"); const requestOptions = { method: "GET", headers: myHeaders, redirect: "follow", }; fetch( "http://openapi.akool.com/api/open/v3/content/video/infobymodelid?video_model_id=66160f989dfc997ac289037b", requestOptions ) .then((response) => response.text()) .then((result) => console.log(result)) .catch((error) => console.error(error)); ``` ```php PHP theme={null} '{{API Key}}' ]; $request = new Request('GET', 'http://openapi.akool.com/api/open/v3/content/video/infobymodelid?video_model_id=66160f989dfc997ac289037b', $headers); $res = $client->sendAsync($request)->wait(); echo $res->getBody(); ``` ```python Python theme={null} import requests url = "http://openapi.akool.com/api/open/v3/content/video/infobymodelid?video_model_id=66160f989dfc997ac289037b" payload = {} headers = { 'x-api-key':'{{API Key}}' } response = requests.request("GET", url, headers=headers, data=payload) print(response.text) ``` **Response** ```json theme={null} { "code": 1000, "msg": "OK", "data": { "faceswap_quality": 2, "storage_loc": 1, "_id": "66160f989dfc997ac289037b", "create_time": 1692242625334, "uid": 378337, "type": 2, "from": 1, "video_id": "788bcd2b-09bb-4e9c-b0f2-6d41ee5b2a67", "video_lock_duration": 7.91, "deduction_lock_duration": 10, "video_status": 2, // current status of video: 【1:queueing(The requested operation is being processed),2:processing(The requested operation is being processing),3:completed(The request operation has been processed successfully),4:failed(The request operation processing failed, the reason for the failure can be viewed in the video translation details.)】 "external_video": "", "video": "" // Generated video resource url } } ``` **Response Code Description** Please note that if the value of the response code is not equal to 1000, the request is failed or wrong | **Parameter** | **Value** | **Description** | | ------------- | --------- | --------------------------------------------------------------------------------- | | code | 1000 | Success | | code | 1003 | Parameter error or Parameter can not beempty | | code | 1008 | The content you get does not exist | | code | 1009 | Youdo not have permission to operate | | code | 1101 | Invalid authorization or Therequest token has expired | | code | 1102 | Authorization cannot be empty | | code | 1200 | The account has been banned | | code | 1201 | create audio error, pleasetry again later | | code | 1202 | The same video cannot be translated lipSync inthe same language more than 1 times | | code | 1203 | video should be with audio | | code | 1204 | Your video duration is exceed 60s! | | code | 1205 | Create videoerror, please try again later | | code | 1207 | The video you are using exceeds thesize limit allowed by the system by 300M | | code | 1209 | Please upload a videoin another encoding format | | code | 1210 | The video you are using exceeds thevalue allowed by the system by 60fp | | code | 1211 | Create lipsync error, pleasetry again later | # Streaming Avatar API Overview Source: https://docs.akool.com/ai-tools-suite/live-avatar Comprehensive guide to the Streaming Avatar API Both the avatar\_id and voice\_id can be easily obtained by copying them directly from the web interface. You can also create and manage your streaming avatars using our intuitive web platform. Create and manage your avatars at: [https://akool.com/apps/upload/avatar?from=%2Fapps%2Fstreaming-avatar%2Fedit](https://akool.com/apps/upload/avatar?from=%2Fapps%2Fstreaming-avatar%2Fedit) The resources (image, video, voice) generated by our API are valid for 7 days. Please save the relevant resources as soon as possible to prevent expiration. To experience our live avatar streaming feature in action, explore our demo built on the Agora streaming service: [AKool Streaming Avatar React Demo](https://github.com/AKOOL-Official/akool-streaming-avatar-react-demo). **Knowledge Base Integration:** You can enhance your streaming avatar with contextual AI responses by integrating a [Knowledge Base](/ai-tools-suite/knowledge-base). When creating a session, provide a `knowledge_id` parameter to enable the AI to use documents and URLs from your knowledge base for more accurate and relevant responses. ### API Endpoints #### Avatar Management * [Upload Streaming Avatar](/ai-tools-suite/live-avatar/upload) - Create a new streaming avatar from a video URL * [Get Avatar List](/ai-tools-suite/live-avatar/list) - Retrieve a list of all streaming avatars * [Get Avatar Detail](/ai-tools-suite/live-avatar/detail) - Get detailed information about a specific avatar #### Session Management * [Create Session](/ai-tools-suite/live-avatar/create-session) - Create a new streaming avatar session * [Get Session Detail](/ai-tools-suite/live-avatar/session-detail) - Retrieve detailed information about a specific session * [Close Session](/ai-tools-suite/live-avatar/close-session) - Close an active streaming avatar session * [Get Session List](/ai-tools-suite/live-avatar/list-sessions) - Retrieve a list of all streaming avatar sessions ### Live Avatar Stream Message ```ts theme={null} IAgoraRTCClient.on(event: "stream-message", listener: (uid: UID, pld: Uint8Array) => void) IAgoraRTCClient.sendStreamMessage(msg: Uint8Array | string, flag: boolean): Promise; ``` **Send Data** **Chat Type Parameters** | **Parameter** | **Type** | **Required** | **Value** | **Description** | | ------------- | -------- | ------------ | --------- | --------------------------------------------------- | | v | Number | Yes | 2 | Version of the message | | type | String | Yes | chat | Message type for chat interactions | | mid | String | Yes | | Unique message identifier for conversation tracking | | idx | Number | Yes | | Sequential index of the message, start from 0 | | fin | Boolean | Yes | | Indicates if this is the final part of the message | | pld | Object | Yes | | Container for message payload | | pld.text | String | Yes | | Text content to send to avatar (e.g. "Hello") | **Command Type Parameters** | **Parameter** | **Type** | **Required** | **Value** | **Description** | | ---------------- | -------- | ------------ | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | v | Number | Yes | 2 | Protocol version number | | type | String | Yes | command | Specifies this is a system command message | | mid | String | Yes | | Unique ID to track and correlate command messages | | pld | Object | Yes | | Contains the command details and parameters | | pld.cmd | String | Yes | | Command action to execute. Valid values: **"set-params"** (update avatar settings), **"interrupt"** (stop current avatar response) | | pld.data | Object | No | | Parameters for the command (required for **"set-params"**) | | pld.data.vid | String | No | | **Deprecated. Use pld.data.vparams.vid instead.** Voice ID to change avatar's voice. Only used with **"set-params"**. Get valid IDs from [Voice List API](/ai-tools-suite/voiceLab#get-voice-list) | | pld.data.vurl | String | No | | **Deprecated. Use pld.data.vparams.vurl instead.** Custom voice model URL. Only used with **"set-params"**. Get valid URLs from [Voice List API](/ai-tools-suite/voiceLab#get-voice-list) | | pld.data.lang | String | No | | Language code for avatar responses (e.g. "en", "es"). Only used with **"set-params"**. Get valid codes from [Language List API](/ai-tools-suite/video-translation#get-language-list-result) | | pld.data.mode | Number | No | | Avatar interaction style. Only used with **"set-params"**. "1" = Retelling (avatar repeats content), "2" = Dialogue (avatar engages in conversation) | | pld.data.bgurl | String | No | | URL of background image/video for avatar scene. Only used with **"set-params"** | | pld.data.vparams | Object | No | | Voice parameters to use for the session. | **Voice Parameters** | **Parameter** | **Type** | **Required** | **Value** | **Description** | | --------------- | -------- | ------------ | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | | vid | String | No | | Voice ID to change avatar's voice. Only used with **"set-params"**. Get valid IDs from [Voice List API](/ai-tools-suite/voiceLab#get-voice-list) | | vurl | String | No | | Custom voice model URL. Only used with **"set-params"**. Get valid URLs from [Voice List API](/ai-tools-suite/voiceLab#get-voice-list) | | speed | double | No | 1 | Controls the speed of the generated speech. Values range from 0.8 to 1.2, with 1.0 being the default speed. | | stt\_language | String | No | | Language code for speech-to-text recognition to improve accuracy by using language-specific models | | pron\_map | Object | No | | Pronunciation mapping for custom words. Example: "pron\_map": \{ "akool" : "ai ku er" } | | stt\_type | String | No | | Speech-to-text type. `"openai_realtime"` = OpenAI Realtime | | turn\_detection | Object | No | | Turn detection configuration. | **Turn Detection Configuration** | **Parameter** | **Type** | **Required** | **Value** | **Description** | | --------------------- | -------- | ------------ | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | type | String | No | "server\_vad" | Turn detection type. `"server_vad"` = Server VAD, `"semantic_vad"` = Semantic VAD | | threshold | Number | No | 0.5 | Activation threshold (0 to 1). A higher threshold will require louder audio to activate the model, and thus might perform better in noisy environments. Available when type is `"server_vad"`. | | prefix\_padding\_ms | Number | No | 300 | Amount of audio (in milliseconds) to include before the VAD detected speech. Available when type is `"server_vad"`. | | silence\_duration\_ms | Number | No | 500 | Duration of silence (in milliseconds) to detect speech stop. With shorter values turns will be detected more quickly. Available when type is `"server_vad"`. | **JSON Example** ```json Chat Request theme={null} { "v": 2, "type": "chat", "mid": "msg-1723629433573", "idx": 0, "fin": true, "pld": { "text": "Hello" }, } ``` ```json Set Avatar Params theme={null} { "v": 2, "type": "command", "mid": "msg-1723629433573", "pld": { "cmd": "set-params", "data": { "vid": "1", "lang": "en", "mode": 1, "bgurl": "https://example.com/background.jpg" } }, } ``` ```json Interrupt Response theme={null} { "v": 2, "type": "command", "mid": "msg-1723629433573", "pld": { "cmd": "interrupt" }, } ``` ```json Set Avatar Actions theme={null} { "v": 2, "type": "command", "pld": { "cmd": "set-action", "data": { "action": "hand_wave", // "hand_wave"|"cheer"|"thumbs_up"|"pump_fists"|"nod"|"shake"|"waft_left"|"waft_right" "expression": "happiness" // "angry"|"disgust"|"fear"|"happiness"|"sadness"|"surprise"|"contempt" } } } ``` **Receive Data** **Chat Type Parameters** | **Parameter** | **Type** | **Value** | **Description** | | ------------- | -------- | --------------- | --------------------------------------------------------------------------------------- | | v | Number | 2 | Version of the message | | type | String | chat | Message type for chat interactions | | mid | String | | Unique message identifier for tracking conversation flow | | idx | Number | | Sequential index of the message part | | fin | Boolean | | Indicates if this is the final part of the response | | pld | Object | | Container for message payload | | pld.from | String | "bot" or "user" | Source of the message - "bot" for avatar responses, "user" for speech recognition input | | pld.text | String | | Text content of the message | **Command Type Parameters** | **Parameter** | **Type** | **Value** | **Description** | | ------------- | -------- | ------------------------- | -------------------------------------------------------------------------------------------------------- | | v | Number | 2 | Version of the message | | type | String | command | Message type for system commands | | mid | String | | Unique identifier for tracking related messages in a conversation | | pld | Object | | Container for command payload | | pld.cmd | String | "set-params", "interrupt" | Command to execute: **"set-params"** to update avatar settings, **"interrupt"** to stop current response | | pld.code | Number | 1000 | Response code from the server, 1000 indicates success | | pld.msg | String | | Response message from the server | **JSON Example** ```json Chat Response theme={null} { "v": 2, "type": "chat", "mid": "msg-1723629433573", "idx": 0, "fin": true, "pld": { "from": "bot", "text": "Hello! How can I assist you today? " } } ``` ```json Command Response theme={null} { "v": 2, "type": "command", "mid": "msg-1723629433573", "pld": { "cmd": "set-params", "code": 1000, "msg": "OK" } } ``` **Typescript Example** ```ts Create Client theme={null} const client: IAgoraRTCClient = AgoraRTC.createClient({ mode: 'rtc', codec: 'vp8', }); client.join(agora_app_id, agora_channel, agora_token, agora_uid); client.on('stream-message', (message: Uint8Array | string) => { console.log('received: %s', message); }); ``` ```ts Send Message theme={null} const msg = JSON.stringify({ v: 2, type: "chat", mid: "msg-1723629433573", idx: 0, fin: true, pld: { text: "hello" }, }); await client.sendStreamMessage(msg, false); ``` ```ts Set Avatar Params theme={null} const setAvatarParams = async () => { const msg = JSON.stringify({ v: 2, type: 'command', pld: { cmd: 'set-params', params: { vid: voiceId, lang: language, mode: modeType, }, }, }); return client.sendStreamMessage(msg, false); }; ``` ```ts Interrupt Response theme={null} const interruptResponse = async () => { const msg = JSON.stringify({ v: 2, type: 'command', pld: { cmd: 'interrupt', }, }); return client.sendStreamMessage(msg, false); }; ``` ### Integrating Your Own LLM Service Before dispatching a message to the WebSocket, consider executing an HTTP request to your LLM service. ```ts TypeScript theme={null} const client: IAgoraRTCClient = AgoraRTC.createClient({ mode: 'rtc', codec: 'vp8', }); client.join(agora_app_id, agora_channel, agora_token, agora_uid); client.on('stream-message', (message: Uint8Array | string) => { console.log('received: %s', message); }); let inputMessage = 'hello'; try { const response = await fetch('https://your-backend-host/api/llm/answer', { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ question: inputMessage, }), }); if (response.ok) { const result = await response.json(); inputMessage = result.answer; } else { console.error("Failed to fetch from backend", response.statusText); } } catch (error) { console.error("Error during fetch operation", error); } const message = { v: 2, type: "chat", mid: "msg-1723629433573", idx: 0, fin: true, pld: { text: inputMessage, }, }; client.sendStreamMessage(JSON.stringify(message), false); ``` ### Response Code Description Please note that if the value of the response code is not equal to 1000, the request is failed or wrong | **Parameter** | **Value** | **Description** | | ------------- | --------- | --------------------------------------------------------------------------------- | | code | 1000 | Success | | code | 1003 | Parameter error or Parameter can not beempty | | code | 1008 | The content you get does not exist | | code | 1009 | Youdo not have permission to operate | | code | 1101 | Invalid authorization or Therequest token has expired | | code | 1102 | Authorization cannot be empty | | code | 1200 | The account has been banned | | code | 1201 | create audio error, pleasetry again later | | code | 1202 | The same video cannot be translated lipSync inthe same language more than 1 times | | code | 1203 | video should be with audio | | code | 1204 | Your video duration is exceed 60s! | | code | 1205 | Create videoerror, please try again later | | code | 1207 | The video you are using exceeds thesize limit allowed by the system by 300M | | code | 1209 | Please upload a videoin another encoding format | | code | 1210 | The video you are using exceeds thevalue allowed by the system by 60fp | | code | 1211 | Create lipsync error, pleasetry again later | # Close Session Source: https://docs.akool.com/ai-tools-suite/live-avatar/close-session POST /api/open/v4/liveAvatar/session/close Close an active streaming avatar session Both the avatar\_id and voice\_id can be easily obtained by copying them directly from the web interface. You can also create and manage your streaming avatars using our intuitive web platform. Create and manage your avatars at: [https://akool.com/apps/upload/avatar?from=%2Fapps%2Fstreaming-avatar%2Fedit](https://akool.com/apps/upload/avatar?from=%2Fapps%2Fstreaming-avatar%2Fedit) ## Code Examples ```bash cURL theme={null} curl -X POST --location "https://openapi.akool.com/api/open/v4/liveAvatar/session/close" \ -H "Authorization: Bearer your_token_here" \ -H "Content-Type: application/json" \ -d '{ "session_id": "session_123456789" }' ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, "{\n \"session_id\": \"session_123456789\"\n}"); Request request = new Request.Builder() .url("https://openapi.akool.com/api/open/v4/liveAvatar/session/close") .method("POST", body) .addHeader("Authorization", "Bearer your_token_here") .addHeader("Content-Type", "application/json") .build(); Response response = client.newCall(request).execute(); ``` ```js Javascript theme={null} const myHeaders = new Headers(); myHeaders.append("Authorization", "Bearer your_token_here"); myHeaders.append("Content-Type", "application/json"); const raw = JSON.stringify({ "session_id": "session_123456789" }); fetch("https://openapi.akool.com/api/open/v4/liveAvatar/session/close", { method: "POST", headers: myHeaders, body: raw }) .then(response => response.text()) .then(result => console.log(result)); ``` ```php PHP theme={null} 'Bearer your_token_here', 'Content-Type' => 'application/json' ]; $body = '{ "session_id": "session_123456789" }'; $request = new Request('POST', 'https://openapi.akool.com/api/open/v4/liveAvatar/session/close', $headers, $body); $res = $client->sendAsync($request)->wait(); echo $res->getBody(); ?> ``` ```python Python theme={null} import requests import json url = "https://openapi.akool.com/api/open/v4/liveAvatar/session/close" payload = json.dumps({ "session_id": "session_123456789" }) headers = { 'Authorization': 'Bearer your_token_here', 'Content-Type': 'application/json' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text) ``` ## Response Example ```json theme={null} { "code": 1000, "msg": "ok", "data": { "session_id": "session_123456789", "status": "closed", "closed_at": 1700788730000 } } ``` # Create Session Source: https://docs.akool.com/ai-tools-suite/live-avatar/create-session POST /api/open/v4/liveAvatar/session/create Create a new streaming avatar session Both the avatar\_id and voice\_id can be easily obtained by copying them directly from the web interface. You can also create and manage your streaming avatars using our intuitive web platform. Create and manage your avatars at: [https://akool.com/apps/upload/avatar?from=%2Fapps%2Fstreaming-avatar%2Fedit](https://akool.com/apps/upload/avatar?from=%2Fapps%2Fstreaming-avatar%2Fedit) **Knowledge Base Integration:** You can enhance your streaming avatar with contextual AI responses by integrating a [Knowledge Base](/ai-tools-suite/knowledge-base). When creating a session, provide a `knowledge_id` parameter to enable the AI to use documents and URLs from your knowledge base for more accurate and relevant responses. **ElevenLabs Custom Configuration:** You can use your own ElevenLabs API key and customize voice parameters by providing `elevenlabs_settings` within the `voice_params` object. This allows you to: * Use your own ElevenLabs account and billing * Choose specific ElevenLabs models (e.g., eleven\_flash\_v2\_5, eleven\_turbo\_v2\_5) * Fine-tune voice characteristics such as stability, similarity\_boost, and style * Enable speaker boost for improved voice cloning quality When using ElevenLabs custom settings, specify your desired ElevenLabs voice ID in the `voice_id` field, and the backend will pass through all your custom parameters to ElevenLabs. # Get Streaming Avatar Detail Source: https://docs.akool.com/ai-tools-suite/live-avatar/detail GET /api/open/v4/liveAvatar/avatar/detail Retrieve detailed information about a specific streaming avatar # Get Streaming Avatar List Source: https://docs.akool.com/ai-tools-suite/live-avatar/list GET /api/open/v4/liveAvatar/avatar/list Retrieve a list of all streaming avatars # Get Session List Source: https://docs.akool.com/ai-tools-suite/live-avatar/list-sessions GET /api/open/v4/liveAvatar/session/list Retrieve a list of all streaming avatar sessions # Get Session Detail Source: https://docs.akool.com/ai-tools-suite/live-avatar/session-detail GET /api/open/v4/liveAvatar/session/detail Retrieve detailed information about a specific streaming avatar session # Upload Streaming Avatar Source: https://docs.akool.com/ai-tools-suite/live-avatar/upload POST /api/open/v3/avatar/create Create a new streaming avatar from a video URL The resources (image, video, voice) generated by our API are valid for 7 days. Please save the relevant resources as soon as possible to prevent expiration. # Vision Sense Source: https://docs.akool.com/ai-tools-suite/live-camera ### Video Interaction With The Avatar To enable video interaction with the avatar, you'll need to publish your local video stream: ```ts theme={null} async function publishVideo(client: IAgoraRTCClient) { // Create a camera video track const videoTrack = await AgoraRTC.createCameraVideoTrack(); try { // Publish the video track to the channel await client.publish(videoTrack); console.log("Video publishing successful"); return videoTrack; } catch (error) { console.error("Error publishing video:", error); throw error; } } // Example usage with video controls async function setupVideoInteraction(client: IAgoraRTCClient) { let videoTrack; // Start video async function startVideo() { try { videoTrack = await publishVideo(client); // Play the local video in a specific HTML element videoTrack.play('local-video-container'); } catch (error) { console.error("Failed to start video:", error); } } // Stop video async function stopVideo() { if (videoTrack) { // Stop and close the video track videoTrack.stop(); videoTrack.close(); await client.unpublish(videoTrack); videoTrack = null; } } // Enable/disable video function toggleVideo(enabled: boolean) { if (videoTrack) { videoTrack.setEnabled(enabled); } } // Switch camera (if multiple cameras are available) async function switchCamera(deviceId: string) { if (videoTrack) { await videoTrack.setDevice(deviceId); } } return { startVideo, stopVideo, toggleVideo, switchCamera }; } ``` The video features now include: * Two-way video communication * Camera switching capabilities * Video quality controls * Integration with existing audio features For more details about Agora's video functionality, refer to the [Agora Web SDK Documentation](https://docs.agora.io/en/video-calling/get-started/get-started-sdk?platform=web#publish-a-local-video-track). # Live Face Swap Source: https://docs.akool.com/ai-tools-suite/live-faceswap Real-time Face Swap API Documentation Generated resources (images, videos) are valid for 7 days. Please save related resources promptly to prevent expiration. ## Overview Live Face Swap API provides real-time face swap functionality, supporting real-time face swap operations during live streaming. ## Get Access Token Before calling other APIs, you need to obtain an access token first. ```bash theme={null} POST https://openapi.akool.com/api/open/v3/getToken ``` **Request Headers** | **Parameter** | **Value** | **Description** | | ------------- | ---------------- | -------------------- | | Content-Type | application/json | Request content type | **Request Body** | **Parameter** | **Type** | **Description** | | ------------- | -------- | --------------- | | clientId | String | Client ID | | clientSecret | String | Client secret | **Example Request** ```json theme={null} { "clientId": "AKX5brZQ***XBQSk=", "clientSecret": "tcMhvgV0fY***WQ2eIoEY70rNi" } ``` ## Face Detection Detect faces in an image and get facial landmarks coordinates. ```bash theme={null} POST https://sg3.akool.com/detect ``` **Request Headers** | **Parameter** | **Value** | **Description** | | ------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | x-api-key | API Key | Your API Key used for request authorization. If both Authorization and x-api-key have values, Authorization will be used first and x-api-key will be discarded. | | Authorization | Bearer `{token}` | Your API Key used for request authorization.[Get Token](/authentication/usage#get-the-token). | | Content-Type | application/json | Request content type | **Request Body** | **Parameter** | **Type** | **Description** | | ------------- | -------- | ---------------------------------- | | single\_face | Boolean | Whether to detect single face only | | image\_url | String | Image URL for face detection | | img | String | Base64 encoded image (optional) | **Example Request** ```json theme={null} { "single_face": false, "image_url": "https://d21ksh0k4smeql.cloudfront.net/1745579943557-yr5w-crop_1728989585247-3239-0-1728989585409-9277.png" } ``` **Response** | **Parameter** | **Type** | **Description** | | -------------- | -------- | ----------------------------------------- | | error\_code | int | Error code (0: success) | | error\_msg | String | Error message | | landmarks | Array | Facial landmarks coordinates array | | landmarks\_str | Array | Facial landmarks coordinates string array | | region | Array | Face region coordinates | | seconds | float | Processing time in seconds | | trx\_id | String | Transaction ID | **Response Example** ```json theme={null} { "error_code": 0, "error_msg": "SUCCESS", "landmarks": [ [ [249, 510], [460, 515], [343, 657], [255, 740], [0, 0], [0, 0] ] ], "landmarks_str": [ "249,510:460,515:343,657:255,740" ], "region": [ [150, 264, 437, 657] ], "seconds": 0.6554102897644043, "trx_id": "64498285-446f-462d-9470-fe36c36c6eac" } ``` ## Create Real-time Face Swap Session Create a new real-time face swap session. ```bash theme={null} POST https://openapi.akool.com/api/open/v3/faceswap/live/create ``` **Request Headers** | **Parameter** | **Value** | **Description** | | ------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | x-api-key | API Key | Your API Key used for request authorization. If both Authorization and x-api-key have values, Authorization will be used first and x-api-key will be discarded. | | Authorization | Bearer `{token}` | Your API Key used for request authorization.[Get Token](/authentication/usage#get-the-token). | | Content-Type | application/json | Request content type | **Request Body** | **Parameter** | **Type** | **Description** | | ------------- | -------- | ------------------------------------------------------------------------------ | | sourceImage | Array | Source image information array, each element contains path and opts properties | **Example Request** ```json theme={null} { "sourceImage": [ { "path": "https://d21ksh0k4smeql.cloudfront.net/crop_1695201165222-7514-0-1695201165485-8149.png", "opts": "262,175:363,175:313,215:272,279" } ] } ``` **Response** | **Parameter** | **Type** | **Description** | | ------------- | -------- | ------------------------------------------------- | | code | int | API response business status code (1000: success) | | msg | String | API response status information | | data | Object | Response data object | **Response Example** ```json theme={null} { "code": 1000, "msg": "OK", "data": { "_id": "684f8fb744b8795862e45cbe", "faceswap_status": 1, "front_user_id": "1", "algorithm_user_id": "3", "front_rtc_token": "007eJxTYFj/uGvaue3C3/VlOLdFmM5UuffmzHGhszbnTSqs3or94HNRYEhNNElJM0oxMkg1MTYxMklMMkm0MDCySDW0sDBOMjRP297vnyHAx8Bw6YAZIyMDIwMLAyMDiM8EJpnBJAuYFGMwMjAyNTAzNDMwNrI0tTQ0MIy3MDIyYWQwBADtwSJM", "channel_id": "20250616032959101_8224", "app_id": "" } } ``` **Status Code Description** * `faceswap_status`: * 1: Queuing * 2: Processing (when this value is 2, the frontend can connect to Agora's server) * 3: Success * 4: Failed ## Update Real-time Face Swap Session Update existing real-time face swap session configuration. ```bash theme={null} POST https://openapi.akool.com/api/open/v3/faceswap/live/update ``` **Request Headers** | **Parameter** | **Value** | **Description** | | ------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | x-api-key | API Key | Your API Key used for request authorization. If both Authorization and x-api-key have values, Authorization will be used first and x-api-key will be discarded. | | Authorization | Bearer `{token}` | Your API Key used for request authorization.[Get Token](/authentication/usage#get-the-token). | | Content-Type | application/json | Request content type | **Request Body** | **Parameter** | **Type** | **Description** | | ------------- | -------- | ------------------------------------------------------------------------------ | | \_id | String | Session ID | | sourceImage | Array | Source image information array, each element contains path and opts properties | **Example Request** ```json theme={null} { "sourceImage": [ { "path": "https://d21ksh0k4smeql.cloudfront.net/1745579943557-yr5w-crop_1728989585247-3239-0-1728989585409-9277.png", "opts": "249,510:460,515:343,657:255,740" } ], "_id": "685ea0bb5aa150dd8b7116b1" } ``` **Response Example** ```json theme={null} { "code": 1000, "msg": "OK" } ``` ## Close Real-time Face Swap Session Close the specified real-time face swap session. ```bash theme={null} POST https://openapi.akool.com/api/open/v3/faceswap/live/close ``` **Request Headers** | **Parameter** | **Value** | **Description** | | ------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | x-api-key | API Key | Your API Key used for request authorization. If both Authorization and x-api-key have values, Authorization will be used first and x-api-key will be discarded. | | Authorization | Bearer `{token}` | Your API Key used for request authorization.[Get Token](/authentication/usage#get-the-token). | | Content-Type | application/json | Request content type | **Request Body** | **Parameter** | **Type** | **Description** | | ------------- | -------- | --------------- | | \_id | String | Session ID | **Example Request** ```json theme={null} { "_id": "685ea0bb5aa150dd8b7116b1" } ``` **Response Example** ```json theme={null} { "code": 1000, "msg": "OK" } ``` ## Code Examples ```bash cURL theme={null} # Get token curl -X POST "https://openapi.akool.com/api/open/v3/getToken" \ -H "Content-Type: application/json" \ -d '{ "clientId": "AKX5brZQ***XBQSk=", "clientSecret": "tcMhvgV0fY***WQ2eIoEY70rNi" }' # Face detection curl -X POST "https://sg3.akool.com/detect" \ -H "x-api-key: {{API Key}}" \ -H "Content-Type: application/json" \ -d '{ "single_face": false, "image_url": "https://d21ksh0k4smeql.cloudfront.net/1745579943557-yr5w-crop_1728989585247-3239-0-1728989585409-9277.png" }' # Create session curl -X POST "https://openapi.akool.com/api/open/v3/faceswap/live/create" \ -H "x-api-key: {{API Key}}" \ -H "Content-Type: application/json" \ -d '{ "sourceImage": [ { "path": "https://d21ksh0k4smeql.cloudfront.net/crop_1695201165222-7514-0-1695201165485-8149.png", "opts": "262,175:363,175:313,215:272,279" } ] }' # Update session curl -X POST "https://openapi.akool.com/api/open/v3/faceswap/live/update" \ -H "x-api-key: {{API Key}}" \ -H "Content-Type: application/json" \ -d '{ "sourceImage": [ { "path": "https://d21ksh0k4smeql.cloudfront.net/1745579943557-yr5w-crop_1728989585247-3239-0-1728989585409-9277.png", "opts": "249,510:460,515:343,657:255,740" } ], "_id": "685ea0bb5aa150dd8b7116b1" }' # Close session curl -X POST "https://openapi.akool.com/api/open/v3/faceswap/live/close" \ -H "x-api-key: {{API Key}}" \ -H "Content-Type: application/json" \ -d '{ "_id": "685ea0bb5aa150dd8b7116b1" }' ``` ```javascript JavaScript theme={null} // Get token const getToken = async () => { const response = await fetch('https://openapi.akool.com/api/open/v3/getToken', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ clientId: 'AKX5brZQ***XBQSk=', clientSecret: 'tcMhvgV0fY***WQ2eIoEY70rNi' }) }); return response.json(); }; // Face detection const detectFace = async (token, imageUrl) => { const response = await fetch('https://sg3.akool.com/detect', { method: 'POST', headers: { 'x-api-key: {{API Key}}', 'Content-Type': 'application/json' }, body: JSON.stringify({ single_face: false, image_url: imageUrl }) }); return response.json(); }; // Create session const createSession = async (token, sourceImage) => { const response = await fetch('https://openapi.akool.com/api/open/v3/faceswap/live/create', { method: 'POST', headers: { 'x-api-key': '{{API Key}}', 'Content-Type': 'application/json' }, body: JSON.stringify({ sourceImage: sourceImage }) }); return response.json(); }; // Update session const updateSession = async (token, sessionId, sourceImage) => { const response = await fetch('https://openapi.akool.com/api/open/v3/faceswap/live/update', { method: 'POST', headers: { 'x-api-key': '{{API Key}}', 'Content-Type': 'application/json' }, body: JSON.stringify({ _id: sessionId, sourceImage: sourceImage }) }); return response.json(); }; // Close session const closeSession = async (token, sessionId) => { const response = await fetch('https://openapi.akool.com/api/open/v3/faceswap/live/close', { method: 'POST', headers: { 'x-api-key': '{{API Key}}', 'Content-Type': 'application/json' }, body: JSON.stringify({ _id: sessionId }) }); return response.json(); }; ``` ```python Python theme={null} import requests import json # Get token def get_token(): url = "https://openapi.akool.com/api/open/v3/getToken" payload = { "clientId": "AKX5brZQ***XBQSk=", "clientSecret": "tcMhvgV0fY***WQ2eIoEY70rNi" } headers = {'Content-Type': 'application/json'} response = requests.post(url, headers=headers, json=payload) return response.json() # Face detection def detect_face(token, image_url): url = "https://sg3.akool.com/detect" payload = { "single_face": False, "image_url": image_url } headers = { 'x-api-key': f'{API Key}', 'Content-Type': 'application/json' } response = requests.post(url, headers=headers, json=payload) return response.json() # Create session def create_session(token, source_image): url = "https://openapi.akool.com/api/open/v3/faceswap/live/create" payload = { "sourceImage": source_image } headers = { 'x-api-key': f'{API Key}', 'Content-Type': 'application/json' } response = requests.post(url, headers=headers, json=payload) return response.json() # Update session def update_session(token, session_id, source_image): url = "https://openapi.akool.com/api/open/v3/faceswap/live/update" payload = { "_id": session_id, "sourceImage": source_image } headers = { 'x-api-key': f'{API Key}', 'Content-Type': 'application/json' } response = requests.post(url, headers=headers, json=payload) return response.json() # Close session def close_session(token, session_id): url = "https://openapi.akool.com/api/open/v3/faceswap/live/close" payload = { "_id": session_id } headers = { 'x-api-key': f'{API Key}', 'Content-Type': 'application/json' } response = requests.post(url, headers=headers, json=payload) return response.json() ``` ## Response Code Description > **Note:** If the `code` value in the response is not `1000`, the request has failed or is incorrect. | **Parameter** | **Value** | **Description** | | ------------- | --------- | ------------------------------------------------------ | | code | 1000 | Success | | code | 1003 | Parameter error or parameter cannot be empty | | code | 1101 | Invalid authorization or the request token has expired | | code | 1102 | Authorization cannot be empty | | code | 1104 | Insufficient quota | ## Important Notes 1. **Resource Validity**: Generated resources are valid for 7 days, please save them promptly 2. **Face Detection**: Use the face-detect API to get face landmarks coordinates before creating face swap sessions 3. **Status Monitoring**: After creating a session, you need to monitor the `faceswap_status` status 4. **Real-time Connection**: When the status is 2, you can connect to Agora's server for real-time face swap 5. **Session Management**: Please close sessions promptly after use to release resources 6. **Error Handling**: Please handle API error codes and error messages properly ## Push and pull stream Demo References For implementing real-time video communication with Agora SDK, you can refer to the following resources: ### Basic Video Calling Demo Parameter Description ![Basic Video Calling Demo Parameter Description](https://d21ksh0k4smeql.cloudfront.net/openapi/images/live-faceswap-demo-ui.png) As shown in the figure above, `channel_id`, `front_user_id`, and `front_rtc_token` correspond to the Channel, User ID, and Token input fields on the page respectively. These parameters can be obtained after creating a session through the Live Face Swap API. After filling them in, you can experience push/pull streaming and real-time face swap effects. ### Demo Page * **Live Demo**: [https://webdemo-global.agora.io/example/basic/basicVideoCall/index.html](https://webdemo-global.agora.io/example/basic/basicVideoCall/index.html) ### Source Code * **GitHub Repository**: [https://github.com/AgoraIO/API-Examples-Web/tree/main/src/example/basic/basicVideoCall](https://github.com/AgoraIO/API-Examples-Web/tree/main/src/example/basic/basicVideoCall) ### Recommended Track Configuration For optimal performance in live face swap scenarios, it's recommended to use the following track configurations: #### Audio Track Configuration ```javascript theme={null} const audioTrack = await AgoraRTC.createMicrophoneAudioTrack({ encoderConfig: "music_standard", }); ``` #### Video Track Configuration ```javascript theme={null} const videoTrack = await AgoraRTC.createCameraVideoTrack({ encoderConfig: { width: 640, height: 480, frameRate: {max: 20, min: 20}, bitrateMin: 5000, bitrateMax: 5000, }, }); ``` These configurations are optimized for: * **Audio**: Using `music_standard` encoder for better audio quality * **Video**: Fixed frame rate at 20fps with controlled bitrate for stable performance * **Resolution**: 640x480 resolution suitable for face swap processing These resources provide complete examples of how to integrate Agora's real-time video communication SDK, which can be used as a reference for implementing the video streaming part of the live face swap functionality. # Reage Source: https://docs.akool.com/ai-tools-suite/reage The resources (image, video, voice) generated by our API are valid for 7 days. Please save the relevant resources as soon as possible to prevent expiration. Experience our age adjustment technology in action by exploring our interactive demo on GitHub: [AKool Reage Demo](https://github.com/AKOOL-Official/akool-reage-demo). ### Image Reage ``` POST https://openapi.akool.com/api/open/v3/faceswap/highquality/imgreage ``` **Request Headers** | **Parameter** | **Value** | **Description** | | ------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | x-api-key | API Key | Your API Key used for request authorization. If both Authorization and x-api-key have values, Authorization will be used first and x-api-key will be discarded. | | Authorization | Bearer `{token}` | Your API Key used for request authorization.[Get Token](/authentication/usage#get-the-token). | **Body Attributes** | Parameter | Type | Value | Description | | ----------- | ------ | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | targetImage | Array | `[{path:"",opts:""}]` | Replacement target image information(Each array element is an object, and the object contains 2 properties, path:Links to faces detected in target images. opts: Key information of the face detected in the target image【You can get it through the face [Face Detect API](/ai-tools-suite/faceswap#face-detect) API, You can get the landmarks\_str value returned by the api interface as the value of opts) | | face\_reage | Int | \[-30, 30] | Reage ranges | | modifyImage | String | | Modify the link address of the image | | webhookUrl | String | | Callback url address based on HTTP request | **Response Attributes** | Parameter | Type | Value | Description | | --------- | ------ | ----------------------------- | ------------------------------------------------------------------------------------------ | | code | int | 1000 | Interface returns business status code(1000:success) | | msg | String | | Interface returns status information | | data | Object | `{_id:"",url: "",job_id: ""}` | `_id`: Interface returns data url: faceswwap result url job\_id: Task processing unique id | **Example** **Body** ```json theme={null} { "targetImage": [ // Replacement target image information { "path": "https://d21ksh0k4smeql.cloudfront.net/crop_1695201103793-0234-0-1695201106985-2306.png", // Links to faces detected in target images "opts": "2804,2182:3607,1897:3341,2566:3519,2920" // Key information of the face detected in the target image【You can get it through the face https://sg3.akool.com/detect API,You can get the landmarks_str value returned by the api interface as the value of opts } ], "face_reage":10,// [-30,30] "modifyImage": "https://d3t6pcz7y7ey7x.cloudfront.net/material1__a92671d0-7960-4028-b2fc-aadd3541f32d.jpg", // Modify the link address of the image "webhookUrl":"" // Callback url address based on HTTP request } ``` **Request** ```bash cURL theme={null} curl --location 'https://openapi.akool.com/api/open/v3/faceswap/highquality/imgreage' \ --header "x-api-key: {{API Key}}" \ --header 'Content-Type: application/json' \ --data '{ "targetImage": [ { "path": "https://d21ksh0k4smeql.cloudfront.net/crop_1695201103793-0234-0-1695201106985-2306.png", "opts": "2804,2182:3607,1897:3341,2566:3519,2920" } ], "face_reage":10, "modifyImage": "https://d3t6pcz7y7ey7x.cloudfront.net/material1__a92671d0-7960-4028-b2fc-aadd3541f32d.jpg", "webhookUrl":"" }' ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, "{\n \"targetImage\": [ \n {\n \"path\": \"https://d21ksh0k4smeql.cloudfront.net/crop_1695201103793-0234-0-1695201106985-2306.png\", \n \"opts\": \"2804,2182:3607,1897:3341,2566:3519,2920\" \n }\n ],\n \"face_reage\":10,\n \"modifyImage\": \"https://d3t6pcz7y7ey7x.cloudfront.net/material1__a92671d0-7960-4028-b2fc-aadd3541f32d.jpg\", \n \"webhookUrl\":\"\" \n}"); Request request = new Request.Builder() .url("https://openapi.akool.com/api/open/v3/faceswap/highquality/imgreage") .method("POST", body) .addHeader("x-api-key", "{{API Key}}") .addHeader("Content-Type", "application/json") .build(); Response response = client.newCall(request).execute(); ``` ```js Javascript theme={null} const myHeaders = new Headers(); myHeaders.append("x-api-key", "{{API Key}}"); myHeaders.append("Content-Type", "application/json"); const raw = JSON.stringify({ "targetImage": [ { "path": "https://d21ksh0k4smeql.cloudfront.net/crop_1695201103793-0234-0-1695201106985-2306.png", "opts": "2804,2182:3607,1897:3341,2566:3519,2920" } ], "face_reage": 10, "modifyImage": "https://d3t6pcz7y7ey7x.cloudfront.net/material1__a92671d0-7960-4028-b2fc-aadd3541f32d.jpg", "webhookUrl": "" }); const requestOptions = { method: "POST", headers: myHeaders, body: raw, redirect: "follow" }; fetch("https://openapi.akool.com/api/open/v3/faceswap/highquality/imgreage", requestOptions) .then((response) => response.text()) .then((result) => console.log(result)) .catch((error) => console.error(error)); ``` ```php PHP theme={null} '{{API Key}}', 'Content-Type' => 'application/json' ]; $body = '{ "targetImage": [ { "path": "https://d21ksh0k4smeql.cloudfront.net/crop_1695201103793-0234-0-1695201106985-2306.png", "opts": "2804,2182:3607,1897:3341,2566:3519,2920" } ], "face_reage": 10, "modifyImage": "https://d3t6pcz7y7ey7x.cloudfront.net/material1__a92671d0-7960-4028-b2fc-aadd3541f32d.jpg", "webhookUrl": "" }'; $request = new Request('POST', 'https://openapi.akool.com/api/open/v3/faceswap/highquality/imgreage', $headers, $body); $res = $client->sendAsync($request)->wait(); echo $res->getBody(); ``` ```python Python theme={null} import requests import json url = "https://openapi.akool.com/api/open/v3/faceswap/highquality/imgreage" payload = json.dumps({ "targetImage": [ { "path": "https://d21ksh0k4smeql.cloudfront.net/crop_1695201103793-0234-0-1695201106985-2306.png", "opts": "2804,2182:3607,1897:3341,2566:3519,2920" } ], "face_reage": 10, "modifyImage": "https://d3t6pcz7y7ey7x.cloudfront.net/material1__a92671d0-7960-4028-b2fc-aadd3541f32d.jpg", "webhookUrl": "" }) headers = { 'x-api-key':'{{API Key}}', 'Content-Type': 'application/json' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text) ``` **Response** ```json theme={null} { "code": 1000, // Interface returns business status code "msg": "Please be patient! If your results are not generated in three hours, please check your input image.", // Interface returns status information "data": { "_id": "6593c94c0ef703e8c055e3c8", // Interface returns data "url": "https://***.cloudfront.net/final_71688047459_.pic-1704184129269-4947-f8abc658-fa82-420f-b1b3-c747d7f18e14-8535.jpg", // faceswwap result url "job_id": "20240102082900592-5653" // Task processing unique id } } ``` ### Video Reage ``` POST https://openapi.akool.com/api/open/v3/faceswap/highquality/vidreage ``` **Request Headers** | **Parameter** | **Value** | **Description** | | ------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | x-api-key | API Key | Your API Key used for request authorization. If both Authorization and x-api-key have values, Authorization will be used first and x-api-key will be discarded. | | Authorization | Bearer `{token}` | Your API Key used for request authorization.[Get Token](/authentication/usage#get-the-token). | **Body Attributes** | Parameter | Type | Value | Description | | ----------- | ------ | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | targetImage | Array | `[]` | Replacement target image information(Each array element is an object, and the object contains 2 properties, path:Links to faces detected in target images. opts: Key information of the face detected in the target image【You can get it through the face [Face Detect API](/ai-tools-suite/faceswap#face-detect) API, You can get the landmarks\_str value returned by the api interface as the value of opts) | | face\_reage | Int | `[-30,30]` | Reage ranges | | modifyVideo | String | | Modify the link address of the video | | webhookUrl | String | | Callback url address based on HTTP request | **Response Attributes** | Parameter | Type | Value | Description | | --------- | ------ | ---------------------------------- | ------------------------------------------------------------------------------------------- | | code | int | 1000 | Interface returns business status code (1000: success) | | msg | String | | Interface returns status information | | data | Object | `{ _id: "", url: "", job_id: "" }` | `_id`: Interface returns data, url: faceswap result url, job\_id: Task processing unique id | **Example** **Body** ```json theme={null} { "targetImage": [ // Replacement target image information { "path": "https://static.website-files.org/assets/images/faceswap/crop_1719224038759-3888-0-1719224039439-1517.jpg", // Links to faces detected in target images "opts": "1408,786:1954,798:1653,1091:1447,1343" // Key information of the face detected in the target image【You can get it through the face https://sg3.akool.com/detect API,You can get the landmarks_str value returned by the api interface as the value of opts } ], "face_reage":10,// [-30,30] "modifyVideo": "https://d3t6pcz7y7ey7x.cloudfront.net/Video10__d2a8cf85-10ae-4c2d-8f4b-d818c0a2e4a4.mp4", // Modify the link address of the video "webhookUrl":"" // Callback url address based on HTTP request } ``` **Request** ```bash cURL theme={null} curl --location 'https://openapi.akool.com/api/open/v3/faceswap/highquality/vidreage' \ --header "x-api-key: {{API Key}}" \ --header 'Content-Type: application/json' \ --data '{ "targetImage": [ // Replacement target image information { "path": "https://static.website-files.org/assets/images/faceswap/crop_1719224038759-3888-0-1719224039439-1517.jpg", // Links to faces detected in target images "opts": "1408,786:1954,798:1653,1091:1447,1343" // Key information of the face detected in the target image【You can get it through the face https://sg3.akool.com/detect API,You can get the landmarks_str value returned by the api interface as the value of opts } ], "face_reage":10,// [-30,30] "modifyVideo": "https://d3t6pcz7y7ey7x.cloudfront.net/Video10__d2a8cf85-10ae-4c2d-8f4b-d818c0a2e4a4.mp4", // Modify the link address of the video "webhookUrl":"" // Callback url address based on HTTP request }' ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, "{\n \"targetImage\": [ \n {\n \"path\": \"https://static.website-files.org/assets/images/faceswap/crop_1719224038759-3888-0-1719224039439-1517.jpg\", \n \"opts\": \"1408,786:1954,798:1653,1091:1447,1343\" \n }\n ],\n \"face_reage\":10,\n \"modifyVideo\": \"https://d3t6pcz7y7ey7x.cloudfront.net/Video10__d2a8cf85-10ae-4c2d-8f4b-d818c0a2e4a4.mp4\", \n \"webhookUrl\":\"\" \n}\n"); Request request = new Request.Builder() .url("https://openapi.akool.com/api/open/v3/faceswap/highquality/vidreage") .method("POST", body) .addHeader("x-api-key", "{{API Key}}") .addHeader("Content-Type", "application/json") .build(); Response response = client.newCall(request).execute(); ``` ```js Javascript theme={null} const myHeaders = new Headers(); myHeaders.append("x-api-key", "{{API Key}}"); myHeaders.append("Content-Type", "application/json"); const raw = JSON.stringify({ "targetImage": [ // Replacement target image information { "path": "https://static.website-files.org/assets/images/faceswap/crop_1719224038759-3888-0-1719224039439-1517.jpg", // Links to faces detected in target images "opts": "1408,786:1954,798:1653,1091:1447,1343" // Key information of the face detected in the target image【You can get it through the face https://sg3.akool.com/detect API,You can get the landmarks_str value returned by the api interface as the value of opts } ], "face_reage":10,// [-30,30] "modifyVideo": "https://d3t6pcz7y7ey7x.cloudfront.net/Video10__d2a8cf85-10ae-4c2d-8f4b-d818c0a2e4a4.mp4", // Modify the link address of the video "webhookUrl":"" // Callback url address based on HTTP request }); const requestOptions = { method: "POST", headers: myHeaders, body: raw, redirect: "follow" }; fetch("https://openapi.akool.com/api/open/v3/faceswap/highquality/vidreage", requestOptions) .then((response) => response.text()) .then((result) => console.log(result)) .catch((error) => console.error(error)); ``` ```php PHP theme={null} '{{API Key}}', 'Content-Type' => 'application/json' ]; $body = '{ "targetImage": [ // Replacement target image information { "path": "https://static.website-files.org/assets/images/faceswap/crop_1719224038759-3888-0-1719224039439-1517.jpg", // Links to faces detected in target images "opts": "1408,786:1954,798:1653,1091:1447,1343" // Key information of the face detected in the target image【You can get it through the face https://sg3.akool.com/detect API,You can get the landmarks_str value returned by the api interface as the value of opts } ], "face_reage":10,// [-30,30] "modifyVideo": "https://d3t6pcz7y7ey7x.cloudfront.net/Video10__d2a8cf85-10ae-4c2d-8f4b-d818c0a2e4a4.mp4", // Modify the link address of the video "webhookUrl":"" // Callback url address based on HTTP request }'; $request = new Request('POST', 'https://openapi.akool.com/api/open/v3/faceswap/highquality/vidreage', $headers, $body); $res = $client->sendAsync($request)->wait(); echo $res->getBody(); ``` ```python Python theme={null} import requests import json url = "https://openapi.akool.com/api/open/v3/faceswap/highquality/vidreage" payload = json.dumps({ "targetImage": [ // Replacement target image information { "path": "https://static.website-files.org/assets/images/faceswap/crop_1719224038759-3888-0-1719224039439-1517.jpg", // Links to faces detected in target images "opts": "1408,786:1954,798:1653,1091:1447,1343" // Key information of the face detected in the target image【You can get it through the face https://sg3.akool.com/detect API,You can get the landmarks_str value returned by the api interface as the value of opts } ], "face_reage":10,// [-30,30] "modifyVideo": "https://d3t6pcz7y7ey7x.cloudfront.net/Video10__d2a8cf85-10ae-4c2d-8f4b-d818c0a2e4a4.mp4", // Modify the link address of the video "webhookUrl":"" // Callback url address based on HTTP request }) headers = { 'x-api-key':'{{API Key}}', 'Content-Type': 'application/json' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text) ``` **Response** ```json theme={null} { "code": 1000, // Interface returns business status code "msg": "Please be patient! If your results are not generated in three hours, please check your input image.", // Interface returns status information "data": { "_id": "6593c94c0ef703e8c055e3c8", // Interface returns data "url": "https://***.cloudfront.net/final_71688047459_.pic-1704184129269-4947-f8abc658-fa82-420f-b1b3-c747d7f18e14-8535.jpg", // faceswwap result url "job_id": "20240102082900592-5653" // Task processing unique id } } ``` ### Get Reage Result List Byids ``` GET https://openapi.akool.com/api/open/v3/faceswap/result/listbyids?_ids=64ef2f27b33f466877701c6a ``` **Request Headers** | **Parameter** | **Value** | **Description** | | ------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | x-api-key | API Key | Your API Key used for request authorization. If both Authorization and x-api-key have values, Authorization will be used first and x-api-key will be discarded. | | Authorization | Bearer `{token}` | Your API Key used for request authorization.[Get Token](/authentication/usage#get-the-token). | **Query Attributes** | Parameter | Type | Value | Description | | --------- | ------ | ----- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `_ids` | String | | Result ids are strings separated by commas. You can get it by returning the `_id` field from [Image Reage API](/ai-tools-suite/reage#image-reage) or [Video Reage API](/ai-tools-suite/reage#video-reage) api. | **Response Attributes** | Parameter | Type | Value | Description | | --------- | ------ | ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | code | int | 1000 | Interface returns business status code (1000: success) | | msg | String | | Interface returns status information | | data | Object | `result: [{ faceswap_status: "", url: "", createdAt: "" }]` | faceswap\_status: faceswap result status (1 In Queue, 2 Processing, 3 Success, 4 Failed), url: faceswap result url, createdAt: current faceswap action created time | **Example** **Request** ```bash cURL theme={null} curl --location 'https://openapi.akool.com/api/open/v3/faceswap/result/listbyids?_ids=64ef2f27b33f466877701c6a' \ --header "x-api-key: {{API Key}}" ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("text/plain"); RequestBody body = RequestBody.create(mediaType, ""); Request request = new Request.Builder() .url("https://openapi.akool.com/api/open/v3/faceswap/result/listbyids?_ids=64ef2f27b33f466877701c6a") .method("GET", body) .addHeader("x-api-key", "{{API Key}}") .build(); Response response = client.newCall(request).execute(); ``` ```js Javascript theme={null} const myHeaders = new Headers(); myHeaders.append("x-api-key", "{{API Key}}"); const requestOptions = { method: "GET", headers: myHeaders, redirect: "follow" }; fetch("https://openapi.akool.com/api/open/v3/faceswap/result/listbyids?_ids=64ef2f27b33f466877701c6a", requestOptions) .then((response) => response.text()) .then((result) => console.log(result)) .catch((error) => console.error(error)); ``` ```php PHP theme={null} '{{API Key}}' ]; $request = new Request('GET', 'https://openapi.akool.com/api/open/v3/faceswap/result/listbyids?_ids=64ef2f27b33f466877701c6a', $headers); $res = $client->sendAsync($request)->wait(); echo $res->getBody(); ``` ```python Python theme={null} import requests url = "https://openapi.akool.com/api/open/v3/faceswap/result/listbyids?_ids=64ef2f27b33f466877701c6a" payload = {} headers = { 'x-api-key':'{{API Key}}' } response = requests.request("GET", url, headers=headers, data=payload) print(response.text) ``` **Response** ```json theme={null} { "code": 1000, // error code "msg": "OK", // api message "data": { "result": [ { "faceswap_type": 1, "faceswap_quality": 2, "faceswap_status": 1, // faceswap result status: 1 In Queue 2 Processing 3 Success 4 failed "deduction_status": 1, "image": 1, "video_duration": 0, "deduction_duration": 0, "update_time": 0, "_id": "64dae65af6e250d4fb2bca63", "userId": "64d985c5571729d3e2999477", "uid": 378337, "url": "https://d21ksh0k4smeql.cloudfront.net/final_material__d71fad6e-a464-43a5-9820-6e4347dce228-80554b9d-2387-4b20-9288-e939952c0ab4-0356.jpg", // faceswwap result url "createdAt": "2023-08-15T02:43:38.536Z" // current faceswap action created time } ] } } ``` ### Reage Task cancel ``` POST https://openapi.akool.com/api/open/v3/faceswap/job/del ``` **Request Headers** | **Parameter** | **Value** | **Description** | | ------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | x-api-key | API Key | Your API Key used for request authorization. If both Authorization and x-api-key have values, Authorization will be used first and x-api-key will be discarded. | | Authorization | Bearer `{token}` | Your API Key used for request authorization.[Get Token](/authentication/usage#get-the-token). | **Body Attributes** | Parameter | Type | Value | Description | | --------- | ------ | ----- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | job\_ids | String | | Task id, You can get it by returning the job\_id field based on [Image Reage API](/ai-tools-suite/reage#image-reage) or [Video Reage API](/ai-tools-suite/reage#video-reage) api. | **Response Attributes** | Parameter | Type | Value | Description | | --------- | ------ | ----- | ------------------------------------------------------ | | code | int | 1000 | Interface returns business status code (1000: success) | | msg | String | | Interface returns status information | **Example** **Body** ```json theme={null} { "job_ids":"" // task id, You can get it by returning the job_id field based on [Image Reage API](/ai-tools-suite/reage#image-reage) or [Video Reage API](/ai-tools-suite/reage#video-reage) api. } ``` **Request** ```bash cURL theme={null} curl --location 'https://openapi.akool.com/api/open/v3/faceswap/job/del' \ --header "x-api-key: {{API Key}}" \ --header 'Content-Type: application/json' \ --data '{ "job_ids":"" }' ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, "{\n \"job_ids\":\"\" \n}"); Request request = new Request.Builder() .url("https://openapi.akool.com/api/open/v3/faceswap/job/del") .method("POST", body) .addHeader("x-api-key", "{{API Key}}") .addHeader("Content-Type", "application/json") .build(); Response response = client.newCall(request).execute(); ``` ```js Javascript theme={null} const myHeaders = new Headers(); myHeaders.append("x-api-key", "{{API Key}}"); myHeaders.append("Content-Type", "application/json"); const raw = JSON.stringify({ "job_ids": "" }); const requestOptions = { method: "POST", headers: myHeaders, body: raw, redirect: "follow" }; fetch("https://openapi.akool.com/api/open/v3/faceswap/job/del", requestOptions) .then((response) => response.text()) .then((result) => console.log(result)) .catch((error) => console.error(error)); ``` ```php PHP theme={null} '{{API Key}}', 'Content-Type' => 'application/json' ]; $body = '{ "job_ids": "" }'; $request = new Request('POST', 'https://openapi.akool.com/api/open/v3/faceswap/job/del', $headers, $body); $res = $client->sendAsync($request)->wait(); echo $res->getBody(); ``` ```python Python theme={null} import requests import json url = "https://openapi.akool.com/api/open/v3/faceswap/job/del" payload = json.dumps({ "job_ids": "" }) headers = { 'x-api-key':'{{API Key}}', 'Content-Type': 'application/json' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text) ``` **Response** ```json theme={null} { "code": 1000, // Business status code "msg": "OK" // The interface returns status information } ``` **Response Code Description** Please note that if the value of the response code is not equal to 1000, the request is failed or wrong | **Parameter** | **Value** | **Description** | | ------------- | --------- | --------------------------------------------------------------------- | | code | 1000 | Success | | code | 1003 | Parameter error or Parameter can not be empty | | code | 1005 | Operation is too frequent | | code | 1006 | Your quota is not enough | | code | 1007 | The number of people who can have their faces changed cannot exceed 8 | | code | 1101 | Invalid authorization or The request token has expired | | code | 1102 | Authorization cannot be empty | | code | 1200 | The account has been banned | # Talking Avatar Source: https://docs.akool.com/ai-tools-suite/talking-avatar Talking Avatar API documentation The resources (image, video, voice) generated by our API are valid for 7 days. Please save the relevant resources as soon as possible to prevent expiration. ### Description * First you need to generate the voice through the following method or directly provide a link to the available voice file * If you want to use the system's sound model to generate speech, you need to generate a link by calling the interface [Create TTS](/ai-tools-suite/voiceLab#create-text-to-speech) * If you want to use the sound model you provide to generate speech, you need to generate a link by calling the interface [Create Voice Clone](/ai-tools-suite/voiceLab#create-voice-clone) * Secondly, you need to provide an avatar link, which can be a picture or video. * If you want to use the avatar provided by the system, you can obtain it through the interface [Get Avatar List](/ai-tools-suite/talking-avatar#get-talking-avatar-list) .Or provide your own avatar url. * Then, you need to generate an avatar video by calling the API [Create Talking Avatar](/ai-tools-suite/talking-avatar#create-talking-avatar) * Finally,The processing status will be returned promptly through the provided callback address, or you can also query it by calling the interface [Get Video Info](/ai-tools-suite/talking-avatar#get-video-info) ### Get Talking Avatar List ```http theme={null} GET https://openapi.akool.com/api/open/v3/avatar/list ``` **Request Headers** | **Parameter** | **Value** | **Description** | | ------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | x-api-key | API Key | Your API Key used for request authorization. If both Authorization and x-api-key have values, Authorization will be used first and x-api-key will be discarded. | | Authorization | Bearer `{token}` | Your API Key used for request authorization.[Get Token](/authentication/usage#get-the-token). | **Query Attributes** | **Parameter** | **Type** | **Value** | **Description** | | ------------- | -------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------- | | from | Number | 2、3 | 2 represents the official avatar of Akool, 3 represents the avatar uploaded by the user themselves,If empty, returns all avatars by default. | | type | Number | 1、2 | 1 represents the talking avatar of Akool, 2 represents the streaming avatar of Akool,If empty, returns all avatars by default. | | page | Number | 1 | Current number of pages,Default is 1. | | size | Number | 10 | Current number of returns per page,Default is 100. | **Response Attributes** | **Parameter** | **Type** | **Value** | **Description** | | ------------- | -------- | -------------------------------- | ----------------------------------------------------------------------------------------------------------------- | | code | int | 1000 | Interface returns business status code(1000:success) | | msg | String | OK | Interface returns status information | | data | Array | `[{ avatar_id: "xx", url: "" }]` | avatar\_id: Used by avatar interface and creating avatar interface. url: You can preview the avatar via the link. | **Example** **Request** ```bash cURL theme={null} curl --location 'https://openapi.akool.com/api/open/v3/avatar/list?from=2&page=1&size=100' \ --header 'x-api-key: {{API Key}}' ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("text/plain"); RequestBody body = RequestBody.create(mediaType, ""); Request request = new Request.Builder() .url("https://openapi.akool.com/api/open/v3/avatar/list?from=2&page=1&size=100") .method("GET", body) .addHeader("x-api-key", "{{API Key}}") .build(); Response response = client.newCall(request).execute(); ``` ```js Javascript theme={null} const myHeaders = new Headers(); myHeaders.append("x-api-key", "{{API Key}}"); const requestOptions = { method: "GET", headers: myHeaders, redirect: "follow", }; fetch( "https://openapi.akool.com/api/open/v3/avatar/list?from=2&page=1&size=100", requestOptions ) .then((response) => response.text()) .then((result) => console.log(result)) .catch((error) => console.error(error)); ``` ```php PHP theme={null} '{{API Key}}' ]; $request = new Request('GET', 'https://openapi.akool.com/api/open/v3/avatar/list?from=2&page=1&size=100', $headers); $res = $client->sendAsync($request)->wait(); echo $res->getBody(); ``` ```python Python theme={null} import requests url = "https://openapi.akool.com/api/open/v3/avatar/list?from=2&page=1&size=100" payload = {} headers = { 'x-api-key': '{{API Key}}' } response = requests.request("GET", url, headers=headers, data=payload) print(response.text) ``` **Response** ```json theme={null} { "code": 1000, "msg": "ok", "data": [ { "name": "Yasmin in White shirt", // avatar name "avatar_id": "Yasmin_in_White_shirt_20231121", // parameter values ​​required to create talkingavatar "url": "https://drz0f01yeq1cx.cloudfront.net/1700786304161-b574407f-f926-4b3e-bba7-dc77d1742e60-8169.png", // avatar url "gender": "female", // avatar gender "thumbnailUrl": "https://drz0f01yeq1cx.cloudfront.net/avatar/thumbnail/1700786304161-b574407f-f926-4b3e-bba7-dc77d1742e60-8169.png", // avatar thumbnail "from": 2 // parameter values ​​required to create talkingavatar } ] } ``` ### Create Talking avatar ``` POST https://openapi.akool.com/api/open/v3/talkingavatar/create ``` **Request Headers** | **Parameter** | **Value** | **Description** | | ------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | x-api-key | API Key | Your API Key used for request authorization. If both Authorization and x-api-key have values, Authorization will be used first and x-api-key will be discarded. | | Authorization | Bearer `{token}` | Your API Key used for request authorization.[Get Token](/authentication/usage#get-the-token). | **Body Attributes** | Parameter | Type | Value | Description | | ----------------------- | --------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | width | Number | 3840 | Set the output video width,must be 3840 | | height | Number | 2160 | Set the output video height,must be 2160 | | avatar\_from | Number | 2 or 3 | You use the avatar from of the avatar model, and you can get from [Get TalkingAvatar List](/ai-tools-suite/talking-avatar#get-avatar-list) api, you will obtain the field 【from】 and pass it here. If you provide an avatar URL yourself, avatar\_from must be 3. | | webhookUrl | String | | Callback url address based on HTTP request. | | elements | \[Object] | | Collection of elements passed in in the video | | \[elements].url | String | | Link to element(When type is equal to image, url can be either a link or a Hexadecimal Color Code). When avatar\_from =2, you don't need to pass this parameter. The image formats currently only support ".png", ".jpg", ".jpeg", ".webp", and the video formats currently only support ".mp4", ".mov", ".avi" | | \[elements].scale\_x | Number | 1 | Horizontal scaling ratio(Required when type is equal to image or avatar) | | \[elements].scale\_y | Number | 1 | Vertical scaling ratio (Required when type is equal to image or avatar) | | \[elements].offset\_x | Number | | Horizontal offset of the upper left corner of the element from the video setting area (in pixels)(Required when type is equal to image or avatar) | | \[elements].offset\_y | Number | | Vertical offset of the upper left corner of the element from the video setting area (in pixels)(Required when type is equal to image or avatar) | | \[elements].height | Number | | The height of the element | | \[elements].width | Number | | The width of the element | | \[elements].type | String | | Element type(avatar、image、audio) | | \[elements].avatar\_id | String | | When type is equal to avatar, you use the avatar\_id of the avatar model, and you can get from [Get TalkingAvatar List](/ai-tools-suite/talking-avatar#get-avatar-list) api, you will obtain the field 【avatar\_id】 and pass it here。 If you provide an avatar URL yourself, you don't need to pass this parameter. | | \[elements].input\_text | String | | Audio element support, for input text, the per-request character limit depends on the subscription plan: Pro – 5,000, Pro Max – 10,000, Business – 50,000. If both the URL and the input text fields are passed, the URL takes precedence. The "input\_text" and "voice\_id" fields must both be present. | | \[elements].voice\_id | String | | Audio element support. [Get Voice List](/ai-tools-suite/voiceLab#get-voice-list) | **Response Attributes** | Parameter | Type | Value | Description | | --------- | ------ | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | | code | int | 1000 | Interface returns business status code (1000:success) | | msg | String | | Interface returns status information | | data | Object | `{ _id:"", video_status:3, video:"" }` | `_id`: Interface returns data status: the status of video: 【1:queueing, 2:processing, 3:completed, 4:failed】, `video`: the url of Generated video | Please note that the generated video link can only be obtained when video\_status is equal to 3. We provide 2 methods: 1. Obtain through [webhook](/ai-tools-suite/webhook#encryption-and-decryption-technology-solution) 2. Obtain by polling the following interface [Get Video Info](/ai-tools-suite/avatar#get-video-info) **Example** **Body** ```json theme={null} { "width": 3840, "height": 2160, "avatar_from": 3, "elements": [ { "type": "image", "url": "https://drz0f01yeq1cx.cloudfront.net/1729480978805-talkingAvatarbg.png", "width": 780, "height": 438, "scale_x": 1, "scale_y": 1, "offset_x": 1920, "offset_y": 1080 }, { "type": "avatar", "url": "https://drz0f01yeq1cx.cloudfront.net/1735009621724-7ce105c6-ed9a-4d13-9061-7e3df59d9798-7953.mp4", "scale_x": 1, "scale_y": 1, "width": 1080, "height": 1080, "offset_x": 1920, "offset_y": 1080 }, { "type": "audio", "url": "https://drz0f01yeq1cx.cloudfront.net/1729666642023-bd6ad5f1-d558-40c7-b720-ad729688f814-6403.mp3", "input_text": "A military parade is a formation of military personnels whose movement is restricted by close-order manoeuvering known as drilling or marching. Large military parades are today held on major holidays and military events around the world.A military parade is a formation of military personnels whose movement is restricted by close-order manoeuvering known as drilling or marching. Large military parades are today held on major holidays and military events around the world.A military parade is a formation of military personnels whose movement is restricted by close-order manoeuvering known as drilling or marching. Large military parades are today held on major holidays and military events around the world.", "voice_id": "6889b628662160e2caad5dbc" } ], "webhookUrl": "" } ``` **Request** ```bash cURL theme={null} curl --location 'https://openapi.akool.com/api/open/v3/talkingavatar/create' \ --header "x-api-key: {{API Key}}" \ --header 'Content-Type: application/json' \ --data '{ "width": 3840, "height": 2160, "avatar_from": 3, "elements": [ { "type": "image", "url": "https://drz0f01yeq1cx.cloudfront.net/1729480978805-talkingAvatarbg.png", "width": 780, "height": 438, "scale_x": 1, "scale_y": 1, "offset_x": 1920, "offset_y": 1080 }, { "type": "avatar", "url": "https://drz0f01yeq1cx.cloudfront.net/1735009621724-7ce105c6-ed9a-4d13-9061-7e3df59d9798-7953.mp4", "scale_x": 1, "scale_y": 1, "width": 1080, "height": 1080, "offset_x": 1920, "offset_y": 1080 }, { "type": "audio", "url": "https://drz0f01yeq1cx.cloudfront.net/1729666642023-bd6ad5f1-d558-40c7-b720-ad729688f814-6403.mp3", "input_text": "A military parade is a formation of military personnels whose movement is restricted by close-order manoeuvering known as drilling or marching. Large military parades are today held on major holidays and military events around the world.A military parade is a formation of military personnels whose movement is restricted by close-order manoeuvering known as drilling or marching. Large military parades are today held on major holidays and military events around the world.A military parade is a formation of military personnels whose movement is restricted by close-order manoeuvering known as drilling or marching. Large military parades are today held on major holidays and military events around the world.", "voice_id": "6889b628662160e2caad5dbc" } ] }' ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, "{\n \"width\": 3840,\n \"height\": 2160,\n \"avatar_from\": 3,\n \"elements\": [\n {\n \"type\": \"image\",\n \"url\": \"https://drz0f01yeq1cx.cloudfront.net/1729480978805-talkingAvatarbg.png\",\n \"width\": 780,\n \"height\": 438,\n \"scale_x\": 1,\n \"scale_y\": 1,\n \"offset_x\": 1920,\n \"offset_y\": 1080\n },\n {\n \"type\": \"avatar\",\n \"url\": \"https://drz0f01yeq1cx.cloudfront.net/1735009621724-7ce105c6-ed9a-4d13-9061-7e3df59d9798-7953.mp4\",\n \"scale_x\": 1,\n \"scale_y\": 1,\n \"width\": 1080,\n \"height\": 1080,\n \"offset_x\": 1920,\n \"offset_y\": 1080\n },\n {\n \"type\": \"audio\",\n \"url\": \"https://drz0f01yeq1cx.cloudfront.net/1729666642023-bd6ad5f1-d558-40c7-b720-ad729688f814-6403.mp3\"\n }\n ]\n}"); Request request = new Request.Builder() .url("https://openapi.akool.com/api/open/v3/talkingavatar/create") .method("POST", body) .addHeader("x-api-key", "{{API Key}}") .addHeader("Content-Type", "application/json") .build(); Response response = client.newCall(request).execute(); ``` ```js Javascript theme={null} const myHeaders = new Headers(); myHeaders.append("x-api-key", "{{API Key}}"); myHeaders.append("Content-Type", "application/json"); const raw = JSON.stringify({ "width": 3840, "height": 2160, "avatar_from": 3, "elements": [ { "type": "image", "url": "https://drz0f01yeq1cx.cloudfront.net/1729480978805-talkingAvatarbg.png", "width": 780, "height": 438, "scale_x": 1, "scale_y": 1, "offset_x": 1920, "offset_y": 1080 }, { "type": "avatar", "url": "https://drz0f01yeq1cx.cloudfront.net/1735009621724-7ce105c6-ed9a-4d13-9061-7e3df59d9798-7953.mp4", "scale_x": 1, "scale_y": 1, "width": 1080, "height": 1080, "offset_x": 1920, "offset_y": 1080 }, { "type": "audio", "url": "https://drz0f01yeq1cx.cloudfront.net/1729666642023-bd6ad5f1-d558-40c7-b720-ad729688f814-6403.mp3", "input_text": "A military parade is a formation of military personnels whose movement is restricted by close-order manoeuvering known as drilling or marching. Large military parades are today held on major holidays and military events around the world.A military parade is a formation of military personnels whose movement is restricted by close-order manoeuvering known as drilling or marching. Large military parades are today held on major holidays and military events around the world.A military parade is a formation of military personnels whose movement is restricted by close-order manoeuvering known as drilling or marching. Large military parades are today held on major holidays and military events around the world.", "voice_id": "6889b628662160e2caad5dbc" } ] }); const requestOptions = { method: "POST", headers: myHeaders, body: raw, redirect: "follow" }; fetch("https://openapi.akool.com/api/open/v3/talkingavatar/create", requestOptions) .then((response) => response.text()) .then((result) => console.log(result)) .catch((error) => console.error(error)); ``` ```php PHP theme={null} '{{API Key}}', 'Content-Type' => 'application/json' ]; $body = '{ "width": 3840, "height": 2160, "avatar_from": 3, "elements": [ { "type": "image", "url": "https://drz0f01yeq1cx.cloudfront.net/1729480978805-talkingAvatarbg.png", "width": 780, "height": 438, "scale_x": 1, "scale_y": 1, "offset_x": 1920, "offset_y": 1080 }, { "type": "avatar", "url": "https://drz0f01yeq1cx.cloudfront.net/1735009621724-7ce105c6-ed9a-4d13-9061-7e3df59d9798-7953.mp4", "scale_x": 1, "scale_y": 1, "width": 1080, "height": 1080, "offset_x": 1920, "offset_y": 1080 }, { "type": "audio", "url": "https://drz0f01yeq1cx.cloudfront.net/1729666642023-bd6ad5f1-d558-40c7-b720-ad729688f814-6403.mp3" } ] }'; $request = new Request('POST', 'https://openapi.akool.com/api/open/v3/talkingavatar/create', $headers, $body); $res = $client->sendAsync($request)->wait(); echo $res->getBody(); ``` ```python Python theme={null} import requests import json url = "https://openapi.akool.com/api/open/v3/talkingavatar/create" payload = json.dumps({ "width": 3840, "height": 2160, "avatar_from": 3, "elements": [ { "type": "image", "url": "https://drz0f01yeq1cx.cloudfront.net/1729480978805-talkingAvatarbg.png", "width": 780, "height": 438, "scale_x": 1, "scale_y": 1, "offset_x": 1920, "offset_y": 1080 }, { "type": "avatar", "url": "https://drz0f01yeq1cx.cloudfront.net/1735009621724-7ce105c6-ed9a-4d13-9061-7e3df59d9798-7953.mp4", "scale_x": 1, "scale_y": 1, "width": 1080, "height": 1080, "offset_x": 1920, "offset_y": 1080 }, { "type": "audio", "url": "https://drz0f01yeq1cx.cloudfront.net/1729666642023-bd6ad5f1-d558-40c7-b720-ad729688f814-6403.mp3" } ] }) headers = { 'x-api-key':'{{API Key}}', 'Content-Type': 'application/json' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text) ``` **Response** ```json theme={null} { "code": 1000, "msg": "OK", "data": { "_id": "67491cdb4d9d1664a9782292", "uid": 100002, "video_id": "f1a489f4-0cca-4723-843b-e42003dc9f32", "task_id": "67491cdb1acd9d0ce2cc8998", "video_status": 1, "video": "", "create_time": 1732844763774 } } ``` ### Get Video Info ``` GET https://openapi.akool.com/api/open/v3/content/video/infobymodelid?video_model_id=64dd838cf0b6684651e90217 ``` **Request Headers** | **Parameter** | **Value** | **Description** | | ------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | x-api-key | API Key | Your API Key used for request authorization. If both Authorization and x-api-key have values, Authorization will be used first and x-api-key will be discarded. | | Authorization | Bearer `{token}` | Your API Key used for request authorization.[Get Token](/authentication/usage#get-the-token). | **Query Attributes** | **Parameter** | **Type** | **Value** | **Description** | | ---------------- | -------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | | video\_model\_id | String | NULL | video db id: You can get it based on the `_id` field returned by [Generate TalkingAvatar](/ai-tools-suite/talking-avatar#create-talking-avatar) . | **Response Attributes** | **Parameter** | **Type** | **Value** | **Description** | | ------------- | -------- | -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | | code | int | 1000 | Interface returns business status code(1000:success) | | msg | String | OK | Interface returns status information | | data | Object | `{ video_status:1, _id:"", video:"" }` | video\_status: the status of video:【1:queueing, 2:processing, 3:completed, 4:failed】 video: Generated video resource url \_id: Interface returns data | **Example** **Request** ```bash cURL theme={null} curl --location 'https://openapi.akool.com/api/open/v3/content/video/infobymodelid?video_model_id=64b126c4a680e8edea44f02b' \ --header "x-api-key: {{API Key}}" ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("text/plain"); RequestBody body = RequestBody.create(mediaType, ""); Request request = new Request.Builder() .url("https://openapi.akool.com/api/open/v3/content/video/infobymodelid?video_model_id=64b126c4a680e8edea44f02b") .method("GET", body) .addHeader("x-api-key", "{{API Key}}") .build(); Response response = client.newCall(request).execute(); ``` ```js Javascript theme={null} const myHeaders = new Headers(); myHeaders.append("x-api-key", "{{API Key}}"); const requestOptions = { method: "GET", headers: myHeaders, redirect: "follow", }; fetch( "https://openapi.akool.com/api/open/v3/content/video/infobymodelid?video_model_id=64b126c4a680e8edea44f02b", requestOptions ) .then((response) => response.text()) .then((result) => console.log(result)) .catch((error) => console.error(error)); ``` ```php PHP theme={null} '{{API Key}}' ]; $request = new Request('GET', 'https://openapi.akool.com/api/open/v3/content/video/infobymodelid?video_model_id=64b126c4a680e8edea44f02b', $headers); $res = $client->sendAsync($request)->wait(); echo $res->getBody(); ``` ```python Python theme={null} import requests url = "https://openapi.akool.com/api/open/v3/content/video/infobymodelid?video_model_id=64b126c4a680e8edea44f02b" payload = {} headers = { 'x-api-key':'{{API Key}}' } response = requests.request("GET", url, headers=headers, data=payload) print(response.text) ``` **Response** ```json theme={null} { "code": 1000, "msg": "OK", "data": { "_id": "64dd92c1f0b6684651e90e09", "create_time": 1692242625334, // content creation time "uid": 378337, "video_id": "0acfed62e24f4cfd8801c9e846347b1d", // video id "deduction_duration": 10, // credits consumed by the final result "video_status": 2, // current status of video: 【1:queueing(The requested operation is being processed),2:processing(The requested operation is being processing),3:completed(The request operation has been processed successfully),4:failed(The request operation processing failed, the reason for the failure can be viewed in the video translation details.)】 "video": "" // Generated video resource url } } ``` ### Get Avatar Detail ``` GET https://openapi.akool.com/api/open/v3/avatar/detail ``` **Request Headers** | **Parameter** | **Value** | **Description** | | ------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | x-api-key | API Key | Your API Key used for request authorization. If both Authorization and x-api-key have values, Authorization will be used first and x-api-key will be discarded. | | Authorization | Bearer `{token}` | Your API Key used for request authorization.[Get Token](/authentication/usage#get-the-token). | **Query Attributes** | **Parameter** | **Type** | **Value** | **Description** | | ------------- | -------- | --------- | ----------------- | | id | String | | avatar record id. | **Response Attributes** | **Parameter** | **Type** | **Value** | **Description** | | ------------- | -------- | -------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | code | int | 1000 | Interface returns business status code(1000:success) | | msg | String | OK | Interface returns status information | | data | Array | `[{ avatar_id: "xx", url: "", status: "" }]` | avatar\_id: Used by avatar interface and creating avatar interface. url: You can preview the avatar via the link. status: 1-queueing 2-processing),3:completed 4-failed | **Example** **Request** ```bash cURL theme={null} curl --location 'https://openapi.akool.com/api/open/v3/avatar/detail?id=66a1a02d591ad336275eda62' \ --header 'x-api-key: {{API Key}}' ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("text/plain"); RequestBody body = RequestBody.create(mediaType, ""); Request request = new Request.Builder() .url("https://openapi.akool.com/api/open/v3/avatar/detail?id=66a1a02d591ad336275eda62") .method("GET", body) .addHeader("x-api-key", "{{API Key}}") .build(); Response response = client.newCall(request).execute(); ``` ```js Javascript theme={null} const myHeaders = new Headers(); myHeaders.append("x-api-key", "{{API Key}}"); const requestOptions = { method: "GET", headers: myHeaders, redirect: "follow", }; fetch( "https://openapi.akool.com/api/open/v3/avatar/detail?id=66a1a02d591ad336275eda62, requestOptions ) .then((response) => response.text()) .then((result) => console.log(result)) .catch((error) => console.error(error)); ``` ```php PHP theme={null} '{{API Key}}' ]; $request = new Request('GET', 'https://openapi.akool.com/api/open/v3/avatar/detail?66a1a02d591ad336275eda62', $headers); $res = $client->sendAsync($request)->wait(); echo $res->getBody(); ``` ```python Python theme={null} import requests url = "https://openapi.akool.com/api/open/v3/avatar/detail?id=66a1a02d591ad336275eda62" payload = {} headers = { 'x-api-key': '{{API Key}}' } response = requests.request("GET", url, headers=headers, data=payload) print(response.text) ``` **Response** ```json theme={null} { "code": 1000, "msg": "ok", "data": [ { "_id": "66a1a02d591ad336275eda62", "uid": 100010, "type": 2, "from": 3, "status": 3, "name": "30870eb0", "url": "https://drz0f01yeq1cx.cloudfront.net/1721868487350-6b4cc614038643eb9f842f4ddc3d5d56.mp4" } ] } ``` ### Upload Talking Avatar ``` POST https://openapi.akool.com/api/open/v3/avatar/create ``` **Request Headers** | **Parameter** | **Value** | **Description** | | ------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | x-api-key | API Key | Your API Key used for request authorization. If both Authorization and x-api-key have values, Authorization will be used first and x-api-key will be discarded. | | Authorization | Bearer `{token}` | Your API Key used for request authorization.[Get Token](/authentication/usage#get-the-token). | **Body Attributes** | **Parameter** | **Type** | **Value** | **Description** | | ------------- | -------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | | url | String | | Avatar resource link. It is recommended that the video be about one minute long, and the avatar in the video content should rotate at a small angle and be clear. | | avatar\_id | String | | avatar unique ID,Can only contain /^a-zA-Z0-9/. | | name | String | | Avatar display name for easier identification and management. | | type | String | 1 | Avatar type, 1 represents talking avatar | **Response Attributes** | **Parameter** | **Type** | **Value** | **Description** | | ------------- | -------- | ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | | code | int | 1000 | Interface returns business status code(1000:success) | | msg | String | OK | Interface returns status information | | data | Array | `[{ avatar_id: "xx", url: "", status: 1 }]` | avatar\_id: Used by creating live avatar interface. url: You can preview the avatar via the link. status: 1-queueing, 2-processing, 3-success, 4-failed | **Example** **Request** ```bash cURL theme={null} curl --location 'https://openapi.akool.com/api/open/v3/avatar/create' \ --header 'x-api-key: {{API Key}}' \ --header 'Content-Type: application/json' \ --data '{ "url": "https://drz0f01yeq1cx.cloudfront.net/1721197444322-leijun000.mp4", "avatar_id": "HHdEKhn7k7vVBlR5FSi0e", "name": "My Talking Avatar", "type": 1 }' ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("text/plain"); RequestBody body = RequestBody.create(mediaType, "{\n \n \"url\": \"https://drz0f01yeq1cx.cloudfront.net/1721197444322-leijun000.mp4\",\n \"avatar_id\": \"HHdEKhn7k7vVBlR5FSi0e\",\n \"name\": \"My Talking Avatar\",\n \"type\": 1\n}"); Request request = new Request.Builder() .url("https://openapi.akool.com/api/open/v3/avatar/create") .method("POST", body) .addHeader("x-api-key", "{{API Key}}") .build(); Response response = client.newCall(request).execute(); ``` ```js Javascript theme={null} const myHeaders = new Headers(); myHeaders.append("x-api-key", "{{API Key}}"); const raw = JSON.stringify({ "url": "https://drz0f01yeq1cx.cloudfront.net/1721197444322-leijun000.mp4", "avatar_id": "HHdEKhn7k7vVBlR5FSi0e", "name": "My Talking Avatar", "type": 1 }); const requestOptions = { method: "POST", headers: myHeaders, redirect: "follow", body: raw }; fetch( "https://openapi.akool.com/api/open/v3/avatar/create", requestOptions ) .then((response) => response.text()) .then((result) => console.log(result)) .catch((error) => console.error(error)); ``` ```php PHP theme={null} '{{API Key}}' ]; $body = '{ "url": "https://drz0f01yeq1cx.cloudfront.net/1721197444322-leijun000.mp4", "avatar_id": "HHdEKhn7k7vVBlR5FSi0e", "name": "My Talking Avatar", "type": 1 }'; $request = new Request('POST', 'https://openapi.akool.com/api/open/v3/avatar/create', $headers, $body); $res = $client->sendAsync($request)->wait(); echo $res->getBody(); ``` ```python Python theme={null} import requests url = "https://openapi.akool.com/api/open/v3/avatar/create" payload = json.dumps({ "url": "https://drz0f01yeq1cx.cloudfront.net/1721197444322-leijun000.mp4", "avatar_id": "HHdEKhn7k7vVBlR5FSi0e", "name": "My Talking Avatar", "type": 1 }); headers = { 'x-api-key': '{{API Key}}' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text) ``` **Response** ```json theme={null} { "code": 1000, "msg": "ok", "data": [ { "_id": "655ffeada6976ea317087193", "disabled": false, "uid": 1, "type": 1, "from": 2, "status": 1, "sort": 12, "create_time": 1700788730000, "name": "Yasmin in White shirt", "avatar_id": "Yasmin_in_White_shirt_20231121", "url": "https://drz0f01yeq1cx.cloudfront.net/1700786304161-b574407f-f926-4b3e-bba7-dc77d1742e60-8169.png", "modify_url": "https://drz0f01yeq1cx.cloudfront.net/1700786304161-b574407f-f926-4b3e-bba7-dc77d1742e60-8169.png", "gender": "female", "thumbnailUrl": "https://drz0f01yeq1cx.cloudfront.net/avatar/thumbnail/1700786304161-b574407f-f926-4b3e-bba7-dc77d1742e60-8169.png", "crop_arr": [] } ] } ``` **Response Code Description** Please note that if the value of the response code is not equal to 1000, the request is failed or wrong | **Parameter** | **Value** | **Description** | | ------------- | --------- | --------------------------------------------- | | code | 1000 | Success | | code | 1003 | Parameter error or Parameter can not be empty | | code | 1006 | Your quota is not enough | | code | 1109 | create avatar video error | | code | 1102 | Authorization cannot be empty | | code | 1200 | The account has been banned | | code | 1201 | Create audio error, please try again later | # Talking Photo API Overview Source: https://docs.akool.com/ai-tools-suite/talking-photo Comprehensive guide to the Talking Photo API The resources (image, video, voice) generated by our API are valid for 7 days. Please save the relevant resources as soon as possible to prevent expiration. Experience our talking photo technology in action by exploring our interactive demo on GitHub: [AKool Talking Photo Demo](https://github.com/AKOOL-Official/akool-talking-photo-demo). ## API Endpoints ### Talking Photo Operations * [Create By Talking Photo](/ai-tools-suite/talking-photo/create-video) - Create animated video from photo and audio * [Get Video Info Result](/ai-tools-suite/talking-photo/get-result) - Retrieve talking photo video results by ID ## Getting Started ### Basic Workflow 1. **Create Talking Photo Video**: * Prepare your talking photo image URL * Prepare your audio URL * Optionally provide prompt * Call the [Create By Talking Photo API](/ai-tools-suite/talking-photo/create-video) with your resources 2. **Check Results**: * Use the [Get Video Info Result API](/ai-tools-suite/talking-photo/get-result) to check the status of your video * Download the result URL when the status is "Success" (video\_status = 3) ### Response Code Description Please note that if the value of the response code is not equal to 1000, the request has failed or encountered an error. | Code | Description | | ---- | ------------------------------------------------------ | | 1000 | Success | | 1003 | Parameter error or Parameter cannot be empty | | 1008 | The content you get does not exist | | 1009 | You do not have permission to operate | | 1015 | Create video error, please try again later | | 1101 | Invalid authorization or The request token has expired | | 1102 | Authorization cannot be empty | | 1200 | The account has been banned | | 1201 | Create audio error, please try again later | ## Talking Photo Status Codes When checking results, the `video_status` field indicates the current state: | Status | Description | | ------ | ------------------------------------------------------------------- | | 1 | In Queue - Your request is waiting to be processed | | 2 | Processing - Talking photo video is currently being generated | | 3 | Success - Video completed, result URL is available | | 4 | Failed - Video generation failed, please check your input resources | ## Best Practices ### Image Requirements * **Quality**: Use high-resolution images for better results * **Face Visibility**: Ensure faces are clearly visible and not obscured * **Lighting**: Well-lit images produce better talking photo results * **Angle**: Frontal or slight angle faces work best ### Audio Requirements * **Quality**: Use clear, high-quality audio files * **Format**: Standard audio formats (MP3 recommended) * **Duration**: Audio duration determines video length ### API Usage Tips * **Webhook**: Use the `webhookUrl` parameter to receive notifications when processing is complete * **Prompt**: Use the `prompt` parameter to control hand gestures for more natural-looking videos * **Resolution**: Choose appropriate resolution (720 or 1080) based on your needs - higher resolution may take longer to process * **Result Cleanup**: Save generated videos promptly as they expire after 7 days ## Common Use Cases ### Basic Talking Photo Video Create a simple talking photo video from an image and audio: ```json theme={null} { "talking_photo_url": "https://example.com/photo.jpg", "audio_url": "https://example.com/audio.mp3", "resolution": "720", "webhookUrl": "" } ``` ### Talking Photo with Prompt Use the `prompt` parameter to control hand gestures for professional presentations: ```json theme={null} { "talking_photo_url": "https://example.com/photo.jpg", "audio_url": "https://example.com/audio.mp3", "prompt": "Throughout the entire video, maintain natural and smooth hand movements. When speaking, use appropriate hand gestures to emphasize key points, such as opening your hands to express welcome or explanation, pointing your fingers forward to emphasize, and placing your hands together to summarize. The gestures should be coherent, not stiff, with moderate amplitude, and the frequency should be coordinated with the speaking speed. During pauses, the gestures naturally return to a relaxed state, presenting a professional and friendly presentation style.", "resolution": "1080", "webhookUrl": "" } ``` ## Support For additional help and examples, check out our: * [GitHub Demo](https://github.com/AKOOL-Official/akool-talking-photo-demo) * [Authentication Guide](/authentication/usage) * [Webhook Documentation](/ai-tools-suite/webhook) # Create By Talking Photo Source: https://docs.akool.com/ai-tools-suite/talking-photo/create-video POST /api/open/v3/content/video/createbytalkingphoto Create animated video from photo and audio The resources (image, video, voice) generated by our API are valid for 7 days. Please save the relevant resources as soon as possible to prevent expiration. Experience our talking photo technology in action by exploring our interactive demo on GitHub: [AKool Talking Photo Demo](https://github.com/AKOOL-Official/akool-talking-photo-demo). ## Important Notes * **Image Quality**: Use high-resolution images with clearly visible faces for better results * **Audio Format**: Standard audio formats (MP3 recommended) * **Prompt**: Use the `prompt` parameter to control hand gestures for more natural and professional-looking videos * **Resolution**: Choose between 720 or 1080 based on your needs - higher resolution may take longer to process * **Resource Expiration**: Generated videos are valid for 7 days, save them promptly * **Webhook**: Use `webhookUrl` to receive notifications when video generation is complete * Save the `_id` from the response to check video status using the [Get Video Info Result](/ai-tools-suite/talking-photo/get-result) API # Get Video Info Result Source: https://docs.akool.com/ai-tools-suite/talking-photo/get-result GET /api/open/v3/content/video/infobymodelid Retrieve talking photo video results by ID ## Important Notes * Use the `_id` field from the [Create By Talking Photo API](/ai-tools-suite/talking-photo/create-video) response as the `video_model_id` parameter * Poll this endpoint periodically to check the video generation status * When `video_status` is 3 (Success), the `video` field will contain the URL of the generated video * Generated videos are valid for 7 days, download and save them promptly ## Video Status | Status | Description | | ------ | -------------------------------------------------- | | 1 | In Queue - Your request is waiting to be processed | | 2 | Processing - Video is currently being generated | | 3 | Success - Video completed, result URL is available | | 4 | Failed - Video generation failed | # Video Translation API Overview Source: https://docs.akool.com/ai-tools-suite/video-translation Comprehensive guide to the Video Translation API for multilingual video content The resources (image, video, voice) generated by our API are valid for 7 days. Please save the relevant resources as soon as possible to prevent expiration. Experience our video translation technology in action by exploring our interactive demo on GitHub: [AKool Video Translation Demo](https://github.com/AKOOL-Official/akool-video-translation-demo). ## API Endpoints ### Translation Operations * [Create Video Translation](/ai-tools-suite/video-translation/create-translation) - Translate videos into multiple languages and lip-sync * [Get Translation Result](/ai-tools-suite/video-translation/get-result) - Check processing status and retrieve translated video URLs ### Resource Management * [Get Language List](/ai-tools-suite/video-translation/get-languages) - Get supported languages for translation ## Getting Started ### Basic Workflow 1. **Get Available Languages**: * Use the [Get Language List API](/ai-tools-suite/video-translation/get-languages) to see all supported target languages * Note which languages require specific voice IDs 2. **Create Translation**: * Call the [Create Video Translation API](/ai-tools-suite/video-translation/create-translation) with your video URL * Set `source_language` to "DEFAULT" for automatic language detection * Specify target languages and optional voice mappings * Configure additional options like lip-sync, captions, and background music removal 3. **Monitor Progress**: * Use the [Get Translation Result API](/ai-tools-suite/video-translation/get-result) to check processing status * Download the translated video URL when status reaches "Completed" (status = 3) ### Key Features #### Automatic Language Detection Set `source_language` to "DEFAULT" to automatically detect the original language of your video content. #### Multiple Language Translation Translate to multiple languages simultaneously by providing comma-separated language codes in the `language` parameter. #### Lip-Sync Technology Enable `lipsync` to synchronize mouth movements with the translated audio for more natural-looking results. #### Caption Support Add, translate, or replace subtitles with various caption handling options. #### Advanced Translation Controls Fine-tune translations with custom word mappings, pronunciation corrections, and translation styles. ## Response Code Description Please note that if the value of the response code is not equal to 1000, the request has failed or encountered an error. | **Code** | **Description** | | -------- | ------------------------------------------------------------------------------------- | | 1000 | Success | | 1003 | Parameter error or Parameter cannot be empty | | 1008 | The content you requested does not exist | | 1009 | You do not have permission to perform this operation | | 1101 | Invalid authorization or The request token has expired | | 1102 | Authorization cannot be empty | | 1200 | The account has been banned | | 1201 | Create audio error, please try again later | | 1202 | The same video cannot be translated with lip-sync in the same language more than once | | 1203 | Video should contain audio | | 1204 | Your video duration exceeds 60 seconds | | 1205 | Create video error, please try again later | | 1207 | The video you are using exceeds the size limit of 300MB | | 1209 | Please upload a video in another encoding format | | 1210 | The video you are using exceeds the frame rate limit of 30fps | ## Video Translation Status Codes When checking results, the `video_status` field indicates the current processing state: | **Status** | **Description** | | ---------- | --------------------------------------------------------------------- | | 1 | Queueing - Your request is waiting to be processed | | 2 | Processing - Video translation is currently being generated | | 3 | Completed - Translation finished successfully, video URL is available | | 4 | Failed - Translation failed, check error details for more information | ## Best Practices ### Video Requirements * **Duration**: Keep videos under 60 seconds for optimal processing time * **Size**: Maximum file size is 300MB * **Frame Rate**: Maximum 30fps supported * **Audio**: Ensure your video contains clear audio for accurate translation * **Encoding**: Use standard encoding formats (H.264 recommended) ### Translation Quality Tips * **Clear Speech**: Videos with clear, well-articulated speech produce better translations * **Background Noise**: Consider using `remove_bgm: true` to remove background music for clearer voice translation * **Speaker Count**: Specify the correct number of speakers for better voice separation ### API Usage Tips * **Webhook**: Use the `webhookUrl` parameter to receive notifications when processing is complete * **Batch Processing**: For multiple videos, process them in parallel but monitor your quota usage * **Error Handling**: Implement proper retry logic for failed translations * **Result Management**: Download and save translated videos promptly as they expire after 7 days ## Common Use Cases ### Single Language Translation ```json theme={null} { "url": "https://example.com/my-video.mp4", "source_language": "DEFAULT", "language": "es", "lipsync": true, } ``` ### Multi-Language Translation ```json theme={null} { "url": "https://example.com/my-video.mp4", "source_language": "DEFAULT", "language": "es,fr,de", "lipsync": false, "caption_type": 2, "remove_bgm": true } ``` ### Professional Translation with Advanced Controls ```json theme={null} { "url": "https://example.com/business-video.mp4", "source_language": "DEFAULT", "language": "zh-CN", "lipsync": true, "studio_voice": { "style": "professional", "no_translate_words": ["AKool", "API"], "fixed_words": {"hello": "您好"} }, "caption_type": 3, "webhookUrl": "https://your-server.com/webhook" } ``` ## Support For additional help and examples, check out our: * [GitHub Demo](https://github.com/AKOOL-Official/akool-video-translation-demo) * [Authentication Guide](/authentication/usage) * [Webhook Documentation](/ai-tools-suite/webhook) # Create Video Translation Source: https://docs.akool.com/ai-tools-suite/video-translation/create-translation POST /api/open/v3/content/video/createbytranslate Translate videos into multiple languages with AI voices and lip-sync Create a video translation job to translate your video content into one or multiple target languages. The API supports automatic source language detection, custom AI voices, lip-sync, and various caption options. The `merge_interval` and `face_enhance` parameters have been deprecated and are no longer supported. # Get Language List Source: https://docs.akool.com/ai-tools-suite/video-translation/get-languages GET /api/open/v3/language/list Retrieve supported languages for video translation Get the complete list of languages supported by the video translation service. This endpoint returns all available target languages along with their language codes and additional metadata. # Get Video Translation Result Source: https://docs.akool.com/ai-tools-suite/video-translation/get-result GET /api/open/v3/content/video/infobymodelid Check the status and retrieve results of video translation jobs Check the processing status of your video translation job and retrieve the translated video URL when completed. Use the `_id` returned from the [Create Video Translation](/ai-tools-suite/video-translation/create-translation) API. ## Status Codes | **Status** | **Description** | | ---------- | ---------------------------------------------------------------------------- | | 1 | Queueing - Your request is waiting to be processed | | 2 | Processing - Video translation is currently being generated | | 3 | Completed - Translation finished successfully, video URL is available | | 4 | Failed - Translation failed, check error\_code and error\_reason for details | # VoiceLab Source: https://docs.akool.com/ai-tools-suite/voiceLab VoiceLab API documentation You can use the following APIs to create voice clones, text-to-speech, voice changer, and manage voice resources. The resources (image, video, voice) generated by our API are valid for 7 days. Please save the relevant resources as soon as possible to prevent expiration. ## Rates | **Plan** | **Pro** | **Max** | **Business** | **Enterprise** | | ------------------- | --------------------------- | --------------------------- | --------------------------- | -------------- | | Text-to-Speech | 4.4 credits/1000 characters | 3.2 credits/1000 characters | 2.4 credits/1000 characters | Customized | | Instant voice clone | 30 voices | 180 voices | 500 voices | Customized | | Voice changer | 4.4 credits/minute | 3.2 credits/minute | 2.4 credits/minute | Customized | ## Models Voice Model Overview: The following multilingual voice models are available for text-to-speech synthesis, each with strong performance across different language families.
Model Name Description Support Languages
Akool Multilingual 1 Performs well on English, Spanish, French, German, Italian, European Portuguese, Dutch, Russian, and other Western languages `ar`,`bg`,`cs`,`da`,`de`,`el`,`en`,`es`, `fi`,`fil`,`fr`,`hi`,`hr`,`hu`,`id`,`it`, `ja`,`ko`,`ms`,`nb`,`nl`,`pl`,`pt`,`ro`, `ru`,`sk`,`sv`,`ta`,`tr`,`uk`,`vi`
Akool Multilingual 2 Excels at text-to-speech across various languages, but does not support voice cloning. `af`,`am`,`ar`,`as`,`az`,`bg`,`bn`,`bs`, `ca`,`cs`,`cy`,`da`,`de`,`el`,`en`,`es`, `et`,`eu`,`fa`,`fi`,`fil`,`fr`,`ga`,`gl`, `gu`,`he`,`hi`,`hr`,`hu`,`hy`,`id`,`is`, `it`,`iu`,`ja`,`jv`,`ka`,`kk`,`km`,`kn`, `ko`,`lo`,`lt`,`lv`,`mk`,`ml`,`mn`,`mr`, `ms`,`mt`,`my`,`nb`,`ne`,`nl`,`or`,`pa`, `pl`,`ps`,`pt`,`ro`,`ru`,`si`,`sk`,`sl`, `so`,`sq`,`sr`,`su`,`sv`,`sw`,`ta`,`te`, `th`,`tr`,`uk`,`ur`,`uz`,`vi`,`zh`,`zu`
Akool Multilingual 3 Performs well on Chinese (Mandarin), Chinese (Cantonese ), Japanese, Korean, as well as English, Spanish, French, and other major Western languages `zh`,`en`,`es`,`fr`,`ru`,`de`,`pt`,`ar`, `it`,`ja`,`ko`,`id`,`vi`,`tr`,`nl`,`uk`, `th`,`pl`,`ro`,`el`,`cs`,`fi`,`hi`,`bg`, `da`,`he`,`ml`,`fa`,`sk`,`sv`,`hr`,`fil`, `hu`,`nb`,`sl`,`ca`,`nn`,`ta`,`af`,`yue`
Akool Multilingual 4 Performs well on Portuguese (Brazil). `en`,`fr`,`de`,`es`,`pt`,`zh`,`ja`,`hi`, `it`,`ko`,`nl`,`pl`,`ru`,`sv`,`tr`
## Create Voice Clone ``` POST https://openapi.akool.com/api/open/v4/voice/clone ``` **Request Headers** | **Parameter** | **Value** | **Description** | | ------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | x-api-key | API Key | Your API Key used for request authorization. If both Authorization and x-api-key have values, Authorization will be used first and x-api-key will be discarded. | | Authorization | Bearer `{token}` | Your API Key used for request authorization.[Get Token](/authentication/usage#get-the-token). | **Body Attributes** | **Parameter** | **Type** | **Required** | **Value** | **Description** | | ----------------------------- | -------- | ------------ | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | source\_voice\_file | String | true | | Original audio file URL, supports mp3, mp4, wav, etc. Must be a public accessible URL, The maximum file size is 30MB. | | voice\_options | Object | false | | Audio tagging options | | - style | Array | false | | Voice style tags (e.g., \["Authoritative", "Calm"]) | | - gender | Array | false | | Gender tags (e.g., \["Male", "Female"]) | | - age | Array | false | | Age tags (e.g., \["Young", "Middle", "Elderly"]) | | - scenario | Array | false | | Use case tags (e.g., \["Advertisement", "Education"]) | | - remove\_background\_noise | Boolean | false | false | Remove background noise, disabled by default | | - language | String | false | en | Language code (ISO 639-1) of the audio file. Defaults to "en" if not specified | | - clone\_prompt | String | false | | Supported voice models: Akool Multilingual 3, Must match the audio content exactly, including punctuation, to enhance clone quality. Sound reproduction example audio. Providing this parameter will help enhance the similarity and stability of the voice synthesis's sound quality. If using this parameter, a small sample audio segment must also be uploaded. The audio file uploaded must comply with the following specifications: The format of the uploaded audio file should be: mp3 or wav format; The duration of the uploaded audio file should be less than 8 seconds; The size of the uploaded audio file should not exceed 20 MB; | | - need\_volume\_normalization | Boolean | false | false | Supported voice models: Akool Multilingual 3, Audio cloning parameter: Enable volume normalization, defaults to false | | name | String | false | | Audio name | | webhookUrl | String | false | | Callback url address based on HTTP request | | voice\_model\_name | String | false | | The designated model for Clone, Supported voice models: Akool Multilingual 1, Akool Multilingual 3, Akool Multilingual 4. [getVoiceModelName](/ai-tools-suite/voiceLab#get-voice-list) | **Response Attributes** | **Parameter** | **Type** | **Value** | **Description** | | --------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | code | int | 1000 | Interface returns business status code(1000:success) | | msg | String | | Interface returns status information | | data | Object | | Response data object | | - uid | Integer | 101400 | User ID | | - team\_id | String | "6805fb69e92d9edc7ca0b409" | Team ID | | - voice\_id | String | null | Voice ID, this value will be updated after task completion, you can view it in the voiceList.[Get Voice List](/ai-tools-suite/voiceLab#get-voice-list) | | - gender | String | "Male" | Voice gender | | - name | String | "MyVoice0626-01" | Voice name | | - preview | String | null | Preview audio URL, this value will be updated after task completion, you can view it in the voiceList.[Get Voice List](/ai-tools-suite/voiceLab#get-voice-list) | | - text | String | "This is a comic style model..." | Preview text content | | - duration | Number | 8064 | Audio duration in milliseconds | | - status | Integer | 1 | Voice clone status: 【1:queueing, 2:processing, 3:completed, 4:failed】 | | - create\_time | Long | 1751349718268 | Creation timestamp | | - style | Array | \["Authoritative", "Calm"] | Voice style tags | | - scenario | Array | \["Advertisenment"] | Use case scenario tags | | - age | Array | \["Elderly", "Middle"] | Age category tags | | - deduction\_credit | Integer | 0 | Deducted credits | | - webhookUrl | String | "Callback URL" | Callback URL | | - \_id | String | "686379d641e5eb74bb8dfe3f" | Document ID | | - source\_voice\_file | String | "[https://drz0f01yeq1cx.cloudfront.net/1751363983518-9431-audio1751363981879.webm](https://drz0f01yeq1cx.cloudfront.net/1751363983518-9431-audio1751363981879.webm)" | Original audio file URL | ### Example **Body** ```json theme={null} { "source_voice_file": "https://drz0f01yeq1cx.cloudfront.net/1755534706613-000a30e917d848d9bd166b636530ae21-38a696952ca94b9eb9ecf07ced494a58.mp3", "name": "My Voice", "voice_options": { "remove_background_noise": true, "style": ["Authoritative","Calm","Confident","Enthusiastic"], "gender": ["Male"], "age": ["Elderly"], "scenario": ["Advertisenment"], "language": "en", "clone_prompt": "In late spring, the peony garden awakens with layers of petals of the Yao Huang and Wei Zi varieties. When the morning dew has not yet dried, the edges of the petals are glistening with crystal-like droplets, and the inner crimson, like silk, gradually deepens, as if the sunset had been cut into a dress. When the wind blows, the sea of flowers surges, and the golden stamens tremble, releasing a faint fragrance that lures bees and butterflies to swirl around the flower centers in golden vortices. The green peony, in particular, when it first blooms, has tips like jade carvings with a hint of moon white, and when it is in full bloom, it is like an ice wine in an emerald cup, making one suspect it is a divine creation from the Queen Mother's Jade Pool. Occasionally, a petal falls, becoming a rolling agate bead on the embroidered carpet, and even the soil is permeated with the elegant fragrance. Such a captivating beauty is why Liu Yuxi wrote that only the peony is truly the national color, and when it blooms, it moves the entire capital. It uses the entire season's brilliance to interpret the grandeur of being the queen of flowers.", "need_volume_normalization": true }, "voice_model_name": "Akool Multilingual 3", "webhookUrl": "" } ``` **Request** ```bash cURL theme={null} curl --location 'https://openapi.akool.com/api/open/v4/voice/clone' \ --header 'x-api-key: {{API Key}}' \ --header 'Content-Type: application/json' \ --data '{ "source_voice_file": "https://drz0f01yeq1cx.cloudfront.net/1755534706613-000a30e917d848d9bd166b636530ae21-38a696952ca94b9eb9ecf07ced494a58.mp3", "name": "My Voice", "voice_options": { "remove_background_noise": true, "style": ["Authoritative","Calm","Confident","Enthusiastic"], "gender": ["Male"], "age": ["Elderly"], "scenario": ["Advertisenment"], "language": "en", "clone_prompt": "In late spring, the peony garden awakens with layers of petals of the Yao Huang and Wei Zi varieties. When the morning dew has not yet dried, the edges of the petals are glistening with crystal-like droplets, and the inner crimson, like silk, gradually deepens, as if the sunset had been cut into a dress. When the wind blows, the sea of flowers surges, and the golden stamens tremble, releasing a faint fragrance that lures bees and butterflies to swirl around the flower centers in golden vortices. The green peony, in particular, when it first blooms, has tips like jade carvings with a hint of moon white, and when it is in full bloom, it is like an ice wine in an emerald cup, making one suspect it is a divine creation from the Queen Mother's Jade Pool. Occasionally, a petal falls, becoming a rolling agate bead on the embroidered carpet, and even the soil is permeated with the elegant fragrance. Such a captivating beauty is why Liu Yuxi wrote that only the peony is truly the national color, and when it blooms, it moves the entire capital. It uses the entire season's brilliance to interpret the grandeur of being the queen of flowers.", "need_volume_normalization": true }, "voice_model_name": "Akool Multilingual 3", "webhookUrl": "" }' ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, "{\n \"source_voice_file\": \"https://drz0f01yeq1cx.cloudfront.net/1755534706613-000a30e917d848d9bd166b636530ae21-38a696952ca94b9eb9ecf07ced494a58.mp3\",\n \"name\": \"Specify Voice Model\",\n \"voice_options\": {\n \"remove_background_noise\": true,\n \"style\": [\"Authoritative\",\"Calm\",\"Confident\",\"Enthusiastic\"],\n \"gender\": [\"Male\"],\n \"age\": [\"Elderly\"],\n \"scenario\": [\"Advertisenment\"],\n \"language\": \"en\",\n \"clone_prompt\": \"In late spring, the peony garden awakens with layers of petals of the Yao Huang and Wei Zi varieties. When the morning dew has not yet dried, the edges of the petals are glistening with crystal-like droplets, and the inner crimson, like silk, gradually deepens, as if the sunset had been cut into a dress. When the wind blows, the sea of flowers surges, and the golden stamens tremble, releasing a faint fragrance that lures bees and butterflies to swirl around the flower centers in golden vortices. The green peony, in particular, when it first blooms, has tips like jade carvings with a hint of moon white, and when it is in full bloom, it is like an ice wine in an emerald cup, making one suspect it is a divine creation from the Queen Mother's Jade Pool. Occasionally, a petal falls, becoming a rolling agate bead on the embroidered carpet, and even the soil is permeated with the elegant fragrance. Such a captivating beauty is why Liu Yuxi wrote that only the peony is truly the national color, and when it blooms, it moves the entire capital. It uses the entire season's brilliance to interpret the grandeur of being the queen of flowers.\",\n \"need_volume_normalization\": true\n },\n \"voice_model_name\": \"Akool Multilingual 3\"\n,\n \"webhookUrl\": \"\"\n}"); Request request = new Request.Builder() .url("https://openapi.akool.com/api/open/v4/voice/clone") .method("POST", body) .addHeader("x-api-key", "{{API Key}}") .addHeader("Content-Type", "application/json") .build(); Response response = client.newCall(request).execute(); ``` ```js Javascript theme={null} const myHeaders = new Headers(); myHeaders.append("x-api-key", "{{API Key}}"); myHeaders.append("Content-Type", "application/json"); const raw = JSON.stringify({ "source_voice_file": "https://drz0f01yeq1cx.cloudfront.net/1755534706613-000a30e917d848d9bd166b636530ae21-38a696952ca94b9eb9ecf07ced494a58.mp3", "name": "Specify Voice Model", "voice_options": { "remove_background_noise": true, "style": ["Authoritative","Calm","Confident","Enthusiastic"], "gender": ["Male"], "age": ["Elderly"], "scenario": ["Advertisenment"], "language": "en", "clone_prompt": "In late spring, the peony garden awakens with layers of petals of the Yao Huang and Wei Zi varieties. When the morning dew has not yet dried, the edges of the petals are glistening with crystal-like droplets, and the inner crimson, like silk, gradually deepens, as if the sunset had been cut into a dress. When the wind blows, the sea of flowers surges, and the golden stamens tremble, releasing a faint fragrance that lures bees and butterflies to swirl around the flower centers in golden vortices. The green peony, in particular, when it first blooms, has tips like jade carvings with a hint of moon white, and when it is in full bloom, it is like an ice wine in an emerald cup, making one suspect it is a divine creation from the Queen Mother's Jade Pool. Occasionally, a petal falls, becoming a rolling agate bead on the embroidered carpet, and even the soil is permeated with the elegant fragrance. Such a captivating beauty is why Liu Yuxi wrote that only the peony is truly the national color, and when it blooms, it moves the entire capital. It uses the entire season's brilliance to interpret the grandeur of being the queen of flowers.", "need_volume_normalization": true }, "voice_model_name": "Akool Multilingual 3", "webhookUrl": "", }); const requestOptions = { method: "POST", headers: myHeaders, body: raw, redirect: "follow" }; fetch("https://openapi.akool.com/api/open/v4/voice/clone", requestOptions) .then((response) => response.text()) .then((result) => console.log(result)) .catch((error) => console.error(error)); ``` ```php PHP theme={null} '{{API Key}}', 'Content-Type' => 'application/json' ]; $body = '{ "source_voice_file": "https://drz0f01yeq1cx.cloudfront.net/1755534706613-000a30e917d848d9bd166b636530ae21-38a696952ca94b9eb9ecf07ced494a58.mp3", "name": "Specify Voice Model", "voice_options": { "remove_background_noise": true, "style": ["Authoritative","Calm","Confident","Enthusiastic"], "gender": ["Male"], "age": ["Elderly"], "scenario": ["Advertisenment"], "language": "en", "clone_prompt": "In late spring, the peony garden awakens with layers of petals of the Yao Huang and Wei Zi varieties. When the morning dew has not yet dried, the edges of the petals are glistening with crystal-like droplets, and the inner crimson, like silk, gradually deepens, as if the sunset had been cut into a dress. When the wind blows, the sea of flowers surges, and the golden stamens tremble, releasing a faint fragrance that lures bees and butterflies to swirl around the flower centers in golden vortices. The green peony, in particular, when it first blooms, has tips like jade carvings with a hint of moon white, and when it is in full bloom, it is like an ice wine in an emerald cup, making one suspect it is a divine creation from the Queen Mother's Jade Pool. Occasionally, a petal falls, becoming a rolling agate bead on the embroidered carpet, and even the soil is permeated with the elegant fragrance. Such a captivating beauty is why Liu Yuxi wrote that only the peony is truly the national color, and when it blooms, it moves the entire capital. It uses the entire season's brilliance to interpret the grandeur of being the queen of flowers.", "need_volume_normalization": true, "webhookUrl": "", }, "voice_model_name": "Akool Multilingual 3" }'; $request = new Request('POST', 'https://openapi.akool.com/api/open/v4/voice/clone', $headers, $body); $res = $client->sendAsync($request)->wait(); echo $res->getBody(); ?> ``` ```python Python theme={null} import requests import json url = "https://openapi.akool.com/api/open/v4/voice/clone" payload = json.dumps({ "source_voice_file": "https://drz0f01yeq1cx.cloudfront.net/1755534706613-000a30e917d848d9bd166b636530ae21-38a696952ca94b9eb9ecf07ced494a58.mp3", "name": "Specify Voice", "voice_options": { "remove_background_noise": true, "style": ["Authoritative","Calm","Confident","Enthusiastic"], "gender": ["Male"], "age": ["Elderly"], "scenario": ["Advertisenment"], "language": "en", "clone_prompt": "In late spring, the peony garden awakens with layers of petals of the Yao Huang and Wei Zi varieties. When the morning dew has not yet dried, the edges of the petals are glistening with crystal-like droplets, and the inner crimson, like silk, gradually deepens, as if the sunset had been cut into a dress. When the wind blows, the sea of flowers surges, and the golden stamens tremble, releasing a faint fragrance that lures bees and butterflies to swirl around the flower centers in golden vortices. The green peony, in particular, when it first blooms, has tips like jade carvings with a hint of moon white, and when it is in full bloom, it is like an ice wine in an emerald cup, making one suspect it is a divine creation from the Queen Mother's Jade Pool. Occasionally, a petal falls, becoming a rolling agate bead on the embroidered carpet, and even the soil is permeated with the elegant fragrance. Such a captivating beauty is why Liu Yuxi wrote that only the peony is truly the national color, and when it blooms, it moves the entire capital. It uses the entire season's brilliance to interpret the grandeur of being the queen of flowers.", "need_volume_normalization": true }, "voice_model_name": "Akool Multilingual 3", "webhookUrl": "", }) headers = { 'x-api-key':'{{API Key}}', 'Content-Type': 'application/json' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text) ``` **Response** ```json theme={null} { "code": 1000, "msg": "OK", "data": { "uid": 101400, "team_id": "6805fb69e92d9edc7ca0b409", "voice_id": null, "gender": "Male", "name": "MyVoice0626-01", "preview": null, "text": "This is a comic style model, this is a comic style model, this is a comic style model, this is a comic style model", "duration": 8064, "status": 1, "create_time": 1751349718268, "style": [ "Authoritative", "Calm" ], "scenario": [ "Advertisenment" ], "age": [ "Elderly", "Middle" ], "deduction_credit": 0, "webhookUrl": "", "source_voice_file": "https://drz0f01yeq1cx.cloudfront.net/1751363983518-9431-audio1751363981879.webm", "_id": "686379d641e5eb74bb8dfe3f" } } ``` ## Create Text to Speech ``` POST https://openapi.akool.com/api/open/v4/voice/tts ``` **Request Headers** | **Parameter** | **Value** | **Description** | | ------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | x-api-key | API Key | Your API Key used for request authorization. If both Authorization and x-api-key have values, Authorization will be used first and x-api-key will be discarded. | | Authorization | Bearer `{token}` | Your API Key used for request authorization.[Get Token](/authentication/usage#get-the-token). | **Body Attributes** | **Parameter** | **Type** | **Required** | **Value** | **Description** | | -------------------------------------- | -------- | ----------------------------------------- | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | input\_text | String | true | | For input text, the per-request character limit depends on the subscription plan: Pro – 5,000, Pro Max – 10,000, Business – 50,000. | | voice\_id | String | true | | Voice ID, Voice synthesis ID. If both timber\_weights and voice\_id fields have values, timber\_weights will not take effect.get this voice\_id from your cloned voices or akool voice list.[getVoiceId](/ai-tools-suite/voiceLab#get-voice-list) | | voice\_options | Object | false | | Audio settings | | - stability | Number | false | | Voice stability (0-1) , Supported voice models: Akool Multilingual 1, [Get Voice Model Name](/ai-tools-suite/voiceLab#get-voice-list) | | - similarity\_boost | Number | false | | Similarity boost (0-1) , Supported voice models: Akool Multilingual 1, [Get Voice Model Name](/ai-tools-suite/voiceLab#get-voice-list) | | - style | Number | false | | Voice style (0-1) , Supported voice models: Akool Multilingual 1, Akool Multilingual 2. Style examples: cheerful, [Get Voice Model Name](/ai-tools-suite/voiceLab#get-voice-list) | | - speed | Number | false | | Speech speed (0.7-1.2) , Supported voice models: Akool Multilingual 1, Akool Multilingual 2, Akool Multilingual 3, [Get Voice Model Name](/ai-tools-suite/voiceLab#get-voice-list) | | - speaker\_boost | Boolean | false | | Speaker boost, Supported voice models: Akool Multilingual 1, [Get Voice Model Name](/ai-tools-suite/voiceLab#get-voice-list) | | - emotion | String | false | | Emotion (happy, sad, angry, fearful, disgusted, surprised, neutral) , It only supports Chinese voice. Supported voice models: Akool Multilingual 2, Akool Multilingual 3, [Get Voice Model Name](/ai-tools-suite/voiceLab#get-voice-list) | | - volume | Integer | false | | Volume (0-100) , Supported voice models: Akool Multilingual 2, Akool Multilingual 3, [Get Voice Model Name](/ai-tools-suite/voiceLab#get-voice-list) | | webhookUrl | String | false | | Callback url address based on HTTP request | | language\_code | String | false | | Currently supported: Akool Multilingual 1, Akool Multilingual 3 and Akool Multilingual 4. When passing in, only Language code (ISO 639-1) such as "zh", "pt" is supported. This parameter is designed to enhance the use of minority languages. Adding audio effects will make it better, but it cannot achieve the effect of translation. | | extra\_options | Object | false | | Additional parameter settings | | - previous\_text | String | false | | Supported voice models: Akool Multilingual 1, [getVoiceModelName](/ai-tools-suite/voiceLab#get-voice-list). The text that came before the text of the current request. Can be used to improve the speech's continuity when concatenating together multiple generations or to influence the speech's continuity in the current generation. | | - next\_text | String | false | | Supported voice models: Akool Multilingual 1, [getVoiceModelName](/ai-tools-suite/voiceLab#get-voice-list). The text that comes after the text of the current request. Can be used to improve the speech's continuity when concatenating together multiple generations or to influence the speech's continuity in the current generation. | | - apply\_text\_normalization | String | false | | Supported voice models: Akool Multilingual 1, [getVoiceModelName](/ai-tools-suite/voiceLab#get-voice-list). This parameter controls text normalization with three modes: ‘auto’, ‘on’, and ‘off’. When set to ‘auto’, the system will automatically decide whether to apply text normalization (e.g., spelling out numbers). With ‘on’, text normalization will always be applied, while with ‘off’, it will be skipped. | | - apply\_language\_text\_normalization | Boolean | false | false | Supported voice models: Akool Multilingual 1, [getVoiceModelName](/ai-tools-suite/voiceLab#get-voice-list). This parameter controls language text normalization. This helps with proper pronunciation of text in some supported languages. WARNING: This parameter can heavily increase the latency of the request. Currently only supported for Japanese. | | - latex\_read | Boolean | false | false | Supported voice models: Akool Multilingual 3, [getVoiceModelName](/ai-tools-suite/voiceLab#get-voice-list). Controls whether to read LaTeX formulas, defaults to false. Note: 1. Formulas in the request must be enclosed with \$\$ 2. Backslashes () in formulas must be escaped as \\ | | - text\_normalization | Boolean | false | false | Supported voice models: Akool Multilingual 3, [getVoiceModelName](/ai-tools-suite/voiceLab#get-voice-list). This parameter supports Chinese and English text normalization, improving performance in number reading scenarios but slightly increasing latency. Defaults to false if not provided. | | - audio\_setting | Object | false | | Supported voice models: Akool Multilingual 3, [getVoiceModelName](/ai-tools-suite/voiceLab#get-voice-list). Audio generation parameter settings | | -- sample\_rate | Integer | false | 32000 | Supported voice models: Akool Multilingual 3, [getVoiceModelName](/ai-tools-suite/voiceLab#get-voice-list). Audio sampling rate. Available range \[8000, 16000, 22050, 24000, 32000, 44100], defaults to 32000 | | -- bitrate | Integer | false | 128000 | Supported voice models: Akool Multilingual 3, [getVoiceModelName](/ai-tools-suite/voiceLab#get-voice-list). Audio bitrate. Available range \[32000, 64000, 128000, 256000], defaults to 128000. This parameter only affects mp3 format audio | | -- format | String | false | mp3 | Supported voice models: Akool Multilingual 3, [getVoiceModelName](/ai-tools-suite/voiceLab#get-voice-list). Audio format. Available options \[mp3, wav], defaults to mp3. WAV format is only supported in non-streaming output | | -- channel | Integer | false | 1 | Supported voice models: Akool Multilingual 3, [getVoiceModelName](/ai-tools-suite/voiceLab#get-voice-list). Number of audio channels. Available options: \[1,2], where 1 is mono and 2 is stereo, defaults to 1 | | - timber\_weights | Array | false | | Supported voice models: Akool Multilingual 3, [getVoiceModelName](/ai-tools-suite/voiceLab#get-voice-list). List of mixed timbres, supporting up to 4 voice timbres. The higher the weight of a single timbre, the more similar the synthesized voice will be to that timbre. If both timber\_weights and voice\_id fields have values, timber\_weights will not take effect. | | -- voice\_id | String | Required within timber\_weights parameter | | Supported voice models: Akool Multilingual 3, [getVoiceModelName](/ai-tools-suite/voiceLab#get-voice-list). Voice timbre ID, must be filled in together with the weight parameter. Get this voice\_id from your cloned voices or akool voice list.[getVoiceId](/ai-tools-suite/voiceLab#get-voice-list) | | -- weight | Integer | Required within timber\_weights parameter | | Supported voice models: Akool Multilingual 3, [getVoiceModelName](/ai-tools-suite/voiceLab#get-voice-list). Weight of each voice timbre, must be filled in together with voice\_id. Available range \[1, 100], the higher the weight, the more similar the synthesized voice will be to that timbre | | - pronunciation\_dict | Object | false | | Supported voice models: Akool Multilingual 3, [getVoiceModelName](/ai-tools-suite/voiceLab#get-voice-list). Pronunciation rules | | -- tone | Array | false | \["燕少飞/(yan4)(shao3)(fei1)", "omg/oh my god"] | Supported voice models: Akool Multilingual 3, [getVoiceModelName](/ai-tools-suite/voiceLab#get-voice-list). Define special pronunciation rules for characters or symbols. For Chinese text, tones are represented by numbers: 1 for first tone, 2 for second tone, 3 for third tone, 4 for fourth tone, 5 for neutral tone | | - voice\_modify | Object | false | | Supported voice models: Akool Multilingual 3, [getVoiceModelName](/ai-tools-suite/voiceLab#get-voice-list). Voice parameter adjustments | | -- pitch | Integer | false | | Supported voice models: Akool Multilingual 3, [getVoiceModelName](/ai-tools-suite/voiceLab#get-voice-list). Pitch adjustment (deep/bright), range \[-100,100]. Values closer to -100 make the voice deeper; closer to 100 make it brighter | | -- intensity | Integer | false | | Supported voice models: Akool Multilingual 3, [getVoiceModelName](/ai-tools-suite/voiceLab#get-voice-list). Intensity adjustment (powerful/soft), range \[-100,100]. Values closer to -100 make the voice more powerful; closer to 100 make it softer | | -- timbre | Integer | false | | Timbre adjustment (resonant/crisp), range \[-100,100]. Values closer to -100 make the voice more resonant; closer to 100 make it crisper | | -- sound\_effects | String | false | | Supported voice models: Akool Multilingual 3, [getVoiceModelName](/ai-tools-suite/voiceLab#get-voice-list). Sound effects settings, only one can be selected at a time. Available options: spacious\_echo (spacious echo), auditorium\_echo (auditorium broadcast), lofi\_telephone (telephone distortion), robotic (electronic voice) | | - subtitle\_enable | Boolean | false | | Supported voice models: Akool Multilingual 3, [getVoiceModelName](/ai-tools-suite/voiceLab#get-voice-list). Controls whether to enable subtitle service, defaults to false. This parameter is only effective in non-streaming output scenarios | | - pitch | Integer | false | | Supported voice models: Akool Multilingual 3, [getVoiceModelName](/ai-tools-suite/voiceLab#get-voice-list). Voice pitch, range \[-12, 12], where 0 outputs the original timbre. Value must be an integer. | **Response Attributes** | **Parameter** | **Type** | **Value** | **Description** | | ------------------- | -------- | -------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | code | int | 1000 | Interface returns business status code(1000:success) | | msg | String | | Interface returns status information | | data | Object | | Response data object | | - create\_time | Long | 1751350015709 | Creation timestamp | | - uid | Integer | 101400 | User ID | | - team\_id | String | "6805fb69e92d9edc7ca0b409" | Team ID | | - input\_text | String | "Welcome to the Akool..." | Input text content | | - preview | String | null | Generated audio URL, this value will be updated after task completion, you can view it in the resourceList.[Get Resource List](/ai-tools-suite/voiceLab#get-voice-results-list) | | - status | Integer | 1 | TTS status: 【1:queueing, 2:processing, 3:completed, 4:failed】 | | - webhookUrl | String | "" | Callback URL | | - duration | Integer | 0 | Audio duration in milliseconds | | - file\_name | String | "1ef1d76ebfc244f7a30430f7049d6ebc.mp3" | Generated file name | | - gender | String | "Male" | Voice gender | | - deduction\_credit | Float | 1.9295 | Deducted credits | | - name | String | "27fec311afd743aa889a057e17e93c13" | Generated name | | - \_id | String | "68637aff41e5eb74bb8dfe73" | Document ID | | - voice\_model\_id | String | "686379d641e5eb74bb8dfe3f" | Voice document ID | | - voice\_id | String | "Tq06jbVyFH4l6R-Gjvo\_V-p\_nVYk5DRrYJZsxeDmlhEtyhcFKKLQODmgngI9llKw" | Voice ID | | - voice\_options | Object | | Voice options object | | - stability | Number |

0.7

| Voice stability setting | | - similarity\_boost | Number |

0.5

| Similarity boost setting | | - style | Number |

0.6

| Voice style setting | | - speed | Number |

0.8

| Speech speed setting | | - speaker\_boost | Boolean |

false

| Speaker boost setting | | - emotion | String |

"happy"

| Emotion setting | | - volume | Integer |

50

| Volume setting | ### Example **Body** ```json theme={null} { "input_text": "In late spring, the peony garden awakens with layers of petals of the Yao Huang and Wei Zi varieties. When the morning dew has not yet dried, the edges of the petals are glistening with crystal-like droplets, and the inner crimson, like silk, gradually deepens, as if the sunset had been cut into a dress. When the wind blows, the sea of flowers surges, and the golden stamens tremble, releasing a faint fragrance that lures bees and butterflies to swirl around the flower centers in golden vortices. The green peony, in particular, when it first blooms, has tips like jade carvings with a hint of moon white, and when it is in full bloom, it is like an ice wine in an emerald cup, making one suspect it is a divine creation from the Queen Mother's Jade Pool. Occasionally, a petal falls, becoming a rolling agate bead on the embroidered carpet, and even the soil is permeated with the elegant fragrance. Such a captivating beauty is why Liu Yuxi wrote that only the peony is truly the national color, and when it blooms, it moves the entire capital. It uses the entire season's brilliance to interpret the grandeur of being the queen of flowers.", "voice_id": "6889b628662160e2caad5dbc", "voice_options": { "stability": 0.6, "similarity_boost": 0.8, "style": 1, "speed": 1.0, "speaker_boost": true, "emotion": "happy", "volume": 80 }, "pitch": -5, "webhookUrl": "", "language_code": "zh", "extra_options": { "previous_text": "In late spring, the peony garden awakens with layers of petals of the Yao Huang and Wei Zi varieties. When the morning dew has not yet dried, the edges of the petals are glistening with crystal-like droplets, and the inner crimson, like silk, gradually deepens, as if the sunset had been cut into a dress. When the wind blows, the sea of flowers surges, and the golden stamens tremble, releasing a faint fragrance that lures bees and butterflies to swirl around the flower centers in golden vortices. The green peony, in particular, when it first blooms, has tips like jade carvings with a hint of moon white, and when it is in full bloom, it is like an ice wine in an emerald cup, making one suspect it is a divine creation from the Queen Mother's Jade Pool. Occasionally, a petal falls, becoming a rolling agate bead on the embroidered carpet, and even the soil is permeated with the elegant fragrance. Such a captivating beauty is why Liu Yuxi wrote that only the peony is truly the national color, and when it blooms, it moves the entire capital. It uses the entire season's brilliance to interpret the grandeur of being the queen of flowers.", "next_text": "In late spring, the peony garden awakens with layers of petals of the Yao Huang and Wei Zi varieties. When the morning dew has not yet dried, the edges of the petals are glistening with crystal-like droplets, and the inner crimson, like silk, gradually deepens, as if the sunset had been cut into a dress. When the wind blows, the sea of flowers surges, and the golden stamens tremble, releasing a faint fragrance that lures bees and butterflies to swirl around the flower centers in golden vortices. The green peony, in particular, when it first blooms, has tips like jade carvings with a hint of moon white, and when it is in full bloom, it is like an ice wine in an emerald cup, making one suspect it is a divine creation from the Queen Mother's Jade Pool. Occasionally, a petal falls, becoming a rolling agate bead on the embroidered carpet, and even the soil is permeated with the elegant fragrance. Such a captivating beauty is why Liu Yuxi wrote that only the peony is truly the national color, and when it blooms, it moves the entire capital. It uses the entire season's brilliance to interpret the grandeur of being the queen of flowers.", "apply_text_normalization": "auto", "apply_language_text_normalization": true, "latex_read": true, "text_normalization": true, "audio_setting": { "sample_rate": 24000, "bitrate": 32000, "format": "mp3", "channel": 2 }, "timber_weights": [ { "voice_id": "6889b7f4662160e2caad60e9", "weight": 80 }, { "voice_id": "6889b7f3662160e2caad60e8", "weight": 60 }, { "voice_id": "6889b7f3662160e2caad60e7", "weight": 30 }, { "voice_id": "6889b7f2662160e2caad60e6", "weight": 10 } ], "pronunciation_dict": { "tone" : [ "雍容/(yong3)(neng4)", "牡丹/(mu4)(dan3)" ] }, "voice_modify": { "pitch": 50, "intensity": 30, "timbre": -50, "sound_effects": "robotic" }, "subtitle_enable": true } } ``` **Request** ```bash cURL theme={null} curl --location 'https://openapi.akool.com/api/open/v4/voice/tts' \ --header 'x-api-key: {{API Key}}' \ --header 'Content-Type: application/json' \ --data '{ "input_text": "In late spring, the peony garden awakens with layers of petals of the Yao Huang and Wei Zi varieties. When the morning dew has not yet dried, the edges of the petals are glistening with crystal-like droplets, and the inner crimson, like silk, gradually deepens, as if the sunset had been cut into a dress. When the wind blows, the sea of flowers surges, and the golden stamens tremble, releasing a faint fragrance that lures bees and butterflies to swirl around the flower centers in golden vortices. The green peony, in particular, when it first blooms, has tips like jade carvings with a hint of moon white, and when it is in full bloom, it is like an ice wine in an emerald cup, making one suspect it is a divine creation from the Queen Mother's Jade Pool. Occasionally, a petal falls, becoming a rolling agate bead on the embroidered carpet, and even the soil is permeated with the elegant fragrance. Such a captivating beauty is why Liu Yuxi wrote that only the peony is truly the national color, and when it blooms, it moves the entire capital. It uses the entire season's brilliance to interpret the grandeur of being the queen of flowers.", "voice_id": "6889b628662160e2caad5dbc", "voice_options": { "stability": 0.6, "similarity_boost": 0.8, "style": 1, "speed": 1.0, "speaker_boost": true, "emotion": "happy", "volume": 80 }, "pitch": -5, "webhookUrl": "", "language_code": "zh", "extra_options": { "previous_text": "In late spring, the peony garden awakens with layers of petals of the Yao Huang and Wei Zi varieties. When the morning dew has not yet dried, the edges of the petals are glistening with crystal-like droplets, and the inner crimson, like silk, gradually deepens, as if the sunset had been cut into a dress. When the wind blows, the sea of flowers surges, and the golden stamens tremble, releasing a faint fragrance that lures bees and butterflies to swirl around the flower centers in golden vortices. The green peony, in particular, when it first blooms, has tips like jade carvings with a hint of moon white, and when it is in full bloom, it is like an ice wine in an emerald cup, making one suspect it is a divine creation from the Queen Mother's Jade Pool. Occasionally, a petal falls, becoming a rolling agate bead on the embroidered carpet, and even the soil is permeated with the elegant fragrance. Such a captivating beauty is why Liu Yuxi wrote that only the peony is truly the national color, and when it blooms, it moves the entire capital. It uses the entire season's brilliance to interpret the grandeur of being the queen of flowers.", "next_text": "In late spring, the peony garden awakens with layers of petals of the Yao Huang and Wei Zi varieties. When the morning dew has not yet dried, the edges of the petals are glistening with crystal-like droplets, and the inner crimson, like silk, gradually deepens, as if the sunset had been cut into a dress. When the wind blows, the sea of flowers surges, and the golden stamens tremble, releasing a faint fragrance that lures bees and butterflies to swirl around the flower centers in golden vortices. The green peony, in particular, when it first blooms, has tips like jade carvings with a hint of moon white, and when it is in full bloom, it is like an ice wine in an emerald cup, making one suspect it is a divine creation from the Queen Mother's Jade Pool. Occasionally, a petal falls, becoming a rolling agate bead on the embroidered carpet, and even the soil is permeated with the elegant fragrance. Such a captivating beauty is why Liu Yuxi wrote that only the peony is truly the national color, and when it blooms, it moves the entire capital. It uses the entire season's brilliance to interpret the grandeur of being the queen of flowers.", "apply_text_normalization": "auto", "apply_language_text_normalization": true, "latex_read": true, "text_normalization": true, "audio_setting": { "sample_rate": 24000, "bitrate": 32000, "format": "mp3", "channel": 2 }, "timber_weights": [ { "voice_id": "6889b7f4662160e2caad60e9", "weight": 80 }, { "voice_id": "6889b7f3662160e2caad60e8", "weight": 60 }, { "voice_id": "6889b7f3662160e2caad60e7", "weight": 30 }, { "voice_id": "6889b7f2662160e2caad60e6", "weight": 10 } ], "pronunciation_dict": { "tone" : [ "雍容/(yong3)(neng4)", "牡丹/(mu4)(dan3)" ] }, "voice_modify": { "pitch": 50, "intensity": 30, "timbre": -50, "sound_effects": "robotic" }, "subtitle_enable": true } }' ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, "{\n \"input_text\": \"In late spring, the peony garden awakens with layers of petals of the Yao Huang and Wei Zi varieties. When the morning dew has not yet dried, the edges of the petals are glistening with crystal-like droplets, and the inner crimson, like silk, gradually deepens, as if the sunset had been cut into a dress. When the wind blows, the sea of flowers surges, and the golden stamens tremble, releasing a faint fragrance that lures bees and butterflies to swirl around the flower centers in golden vortices. The green peony, in particular, when it first blooms, has tips like jade carvings with a hint of moon white, and when it is in full bloom, it is like an ice wine in an emerald cup, making one suspect it is a divine creation from the Queen Mother's Jade Pool. Occasionally, a petal falls, becoming a rolling agate bead on the embroidered carpet, and even the soil is permeated with the elegant fragrance. Such a captivating beauty is why Liu Yuxi wrote that only the peony is truly the national color, and when it blooms, it moves the entire capital. It uses the entire season's brilliance to interpret the grandeur of being the queen of flowers.\",\n \"voice_id\": \"6889b628662160e2caad5dbc\",\n \"voice_options\": {\n \"stability\": 0.6,\n \"similarity_boost\": 0.8,\n \"style\": 1,\n \"speed\": 1.0,\n \"speaker_boost\": true,\n \"emotion\": \"happy\",\n \"volume\": 80\n },\n \"pitch\": -5,\n \"webhookUrl\": \"\",\n \"language_code\": \"zh\",\n \"extra_options\": {\n \"previous_text\": \"In late spring, the peony garden awakens with layers of petals of the Yao Huang and Wei Zi varieties. When the morning dew has not yet dried, the edges of the petals are glistening with crystal-like droplets, and the inner crimson, like silk, gradually deepens, as if the sunset had been cut into a dress. When the wind blows, the sea of flowers surges, and the golden stamens tremble, releasing a faint fragrance that lures bees and butterflies to swirl around the flower centers in golden vortices. The green peony, in particular, when it first blooms, has tips like jade carvings with a hint of moon white, and when it is in full bloom, it is like an ice wine in an emerald cup, making one suspect it is a divine creation from the Queen Mother's Jade Pool. Occasionally, a petal falls, becoming a rolling agate bead on the embroidered carpet, and even the soil is permeated with the elegant fragrance. Such a captivating beauty is why Liu Yuxi wrote that only the peony is truly the national color, and when it blooms, it moves the entire capital. It uses the entire season's brilliance to interpret the grandeur of being the queen of flowers.\",\n \"next_text\": \"In late spring, the peony garden awakens with layers of petals of the Yao Huang and Wei Zi varieties. When the morning dew has not yet dried, the edges of the petals are glistening with crystal-like droplets, and the inner crimson, like silk, gradually deepens, as if the sunset had been cut into a dress. When the wind blows, the sea of flowers surges, and the golden stamens tremble, releasing a faint fragrance that lures bees and butterflies to swirl around the flower centers in golden vortices. The green peony, in particular, when it first blooms, has tips like jade carvings with a hint of moon white, and when it is in full bloom, it is like an ice wine in an emerald cup, making one suspect it is a divine creation from the Queen Mother's Jade Pool. Occasionally, a petal falls, becoming a rolling agate bead on the embroidered carpet, and even the soil is permeated with the elegant fragrance. Such a captivating beauty is why Liu Yuxi wrote that only the peony is truly the national color, and when it blooms, it moves the entire capital. It uses the entire season's brilliance to interpret the grandeur of being the queen of flowers.\",\n \"apply_text_normalization\": \"auto\",\n \"apply_language_text_normalization\": true,\n \"latex_read\": true,\n \"text_normalization\": true,\n \"audio_setting\": {\n \"sample_rate\": 24000,\n \"bitrate\": 32000,\n \"format\": \"mp3\",\n \"channel\": 2\n },\n \"timber_weights\": [\n {\n \"voice_id\": \"6889b7f4662160e2caad60e9\",\n \"weight\": 80\n },\n {\n \"voice_id\": \"6889b7f3662160e2caad60e8\",\n \"weight\": 60\n },\n {\n \"voice_id\": \"6889b7f3662160e2caad60e7\",\n \"weight\": 30\n },\n {\n \"voice_id\": \"6889b7f2662160e2caad60e6\",\n \"weight\": 10\n }\n ],\n \"pronunciation_dict\": {\n \"tone\" : [\n \"雍容/(yong3)(neng4)\",\n \"牡丹/(mu4)(dan3)\"\n ]\n },\n \"voice_modify\": {\n \"pitch\": 50,\n \"intensity\": 30,\n \"timbre\": -50,\n \"sound_effects\": \"robotic\"\n },\n \"subtitle_enable\": true\n }\n}"); Request request = new Request.Builder() .url("https://openapi.akool.com/api/open/v4/voice/tts") .method("POST", body) .addHeader("x-api-key", "{{API Key}}") .addHeader("Content-Type", "application/json") .build(); Response response = client.newCall(request).execute(); ``` ```js Javascript theme={null} const myHeaders = new Headers(); myHeaders.append("x-api-key", "{{API Key}}"); myHeaders.append("Content-Type", "application/json"); const raw = JSON.stringify({ "input_text": "In late spring, the peony garden awakens with layers of petals of the Yao Huang and Wei Zi varieties. When the morning dew has not yet dried, the edges of the petals are glistening with crystal-like droplets, and the inner crimson, like silk, gradually deepens, as if the sunset had been cut into a dress. When the wind blows, the sea of flowers surges, and the golden stamens tremble, releasing a faint fragrance that lures bees and butterflies to swirl around the flower centers in golden vortices. The green peony, in particular, when it first blooms, has tips like jade carvings with a hint of moon white, and when it is in full bloom, it is like an ice wine in an emerald cup, making one suspect it is a divine creation from the Queen Mother's Jade Pool. Occasionally, a petal falls, becoming a rolling agate bead on the embroidered carpet, and even the soil is permeated with the elegant fragrance. Such a captivating beauty is why Liu Yuxi wrote that only the peony is truly the national color, and when it blooms, it moves the entire capital. It uses the entire season's brilliance to interpret the grandeur of being the queen of flowers.", "voice_id": "6889b628662160e2caad5dbc", "voice_options": { "stability": 0.6, "similarity_boost": 0.8, "style": 1, "speed": 1.0, "speaker_boost": true, "emotion": "happy", "volume": 80 }, "pitch": -5, "webhookUrl": "", "language_code": "zh", "extra_options": { "previous_text": "In late spring, the peony garden awakens with layers of petals of the Yao Huang and Wei Zi varieties. When the morning dew has not yet dried, the edges of the petals are glistening with crystal-like droplets, and the inner crimson, like silk, gradually deepens, as if the sunset had been cut into a dress. When the wind blows, the sea of flowers surges, and the golden stamens tremble, releasing a faint fragrance that lures bees and butterflies to swirl around the flower centers in golden vortices. The green peony, in particular, when it first blooms, has tips like jade carvings with a hint of moon white, and when it is in full bloom, it is like an ice wine in an emerald cup, making one suspect it is a divine creation from the Queen Mother's Jade Pool. Occasionally, a petal falls, becoming a rolling agate bead on the embroidered carpet, and even the soil is permeated with the elegant fragrance. Such a captivating beauty is why Liu Yuxi wrote that only the peony is truly the national color, and when it blooms, it moves the entire capital. It uses the entire season's brilliance to interpret the grandeur of being the queen of flowers.", "next_text": "In late spring, the peony garden awakens with layers of petals of the Yao Huang and Wei Zi varieties. When the morning dew has not yet dried, the edges of the petals are glistening with crystal-like droplets, and the inner crimson, like silk, gradually deepens, as if the sunset had been cut into a dress. When the wind blows, the sea of flowers surges, and the golden stamens tremble, releasing a faint fragrance that lures bees and butterflies to swirl around the flower centers in golden vortices. The green peony, in particular, when it first blooms, has tips like jade carvings with a hint of moon white, and when it is in full bloom, it is like an ice wine in an emerald cup, making one suspect it is a divine creation from the Queen Mother's Jade Pool. Occasionally, a petal falls, becoming a rolling agate bead on the embroidered carpet, and even the soil is permeated with the elegant fragrance. Such a captivating beauty is why Liu Yuxi wrote that only the peony is truly the national color, and when it blooms, it moves the entire capital. It uses the entire season's brilliance to interpret the grandeur of being the queen of flowers.", "apply_text_normalization": "auto", "apply_language_text_normalization": true, "latex_read": true, "text_normalization": true, "audio_setting": { "sample_rate": 24000, "bitrate": 32000, "format": "mp3", "channel": 2 }, "timber_weights": [ { "voice_id": "6889b7f4662160e2caad60e9", "weight": 80 }, { "voice_id": "6889b7f3662160e2caad60e8", "weight": 60 }, { "voice_id": "6889b7f3662160e2caad60e7", "weight": 30 }, { "voice_id": "6889b7f2662160e2caad60e6", "weight": 10 } ], "pronunciation_dict": { "tone" : [ "雍容/(yong3)(neng4)", "牡丹/(mu4)(dan3)" ] }, "voice_modify": { "pitch": 50, "intensity": 30, "timbre": -50, "sound_effects": "robotic" }, "subtitle_enable": true } }); const requestOptions = { method: "POST", headers: myHeaders, body: raw, redirect: "follow" }; fetch("https://openapi.akool.com/api/open/v4/voice/tts", requestOptions) .then((response) => response.text()) .then((result) => console.log(result)) .catch((error) => console.error(error)); ``` ```php PHP theme={null} '{{API Key}}', 'Content-Type' => 'application/json' ]; $body = '{ "input_text": "In late spring, the peony garden awakens with layers of petals of the Yao Huang and Wei Zi varieties. When the morning dew has not yet dried, the edges of the petals are glistening with crystal-like droplets, and the inner crimson, like silk, gradually deepens, as if the sunset had been cut into a dress. When the wind blows, the sea of flowers surges, and the golden stamens tremble, releasing a faint fragrance that lures bees and butterflies to swirl around the flower centers in golden vortices. The green peony, in particular, when it first blooms, has tips like jade carvings with a hint of moon white, and when it is in full bloom, it is like an ice wine in an emerald cup, making one suspect it is a divine creation from the Queen Mother's Jade Pool. Occasionally, a petal falls, becoming a rolling agate bead on the embroidered carpet, and even the soil is permeated with the elegant fragrance. Such a captivating beauty is why Liu Yuxi wrote that only the peony is truly the national color, and when it blooms, it moves the entire capital. It uses the entire season's brilliance to interpret the grandeur of being the queen of flowers.", "voice_id": "6889b628662160e2caad5dbc", "voice_options": { "stability": 0.6, "similarity_boost": 0.8, "style": 1, "speed": 1.0, "speaker_boost": true, "emotion": "happy", "volume": 80 }, "pitch": -5, "webhookUrl": "", "language_code": "zh", "extra_options": { "previous_text": "In late spring, the peony garden awakens with layers of petals of the Yao Huang and Wei Zi varieties. When the morning dew has not yet dried, the edges of the petals are glistening with crystal-like droplets, and the inner crimson, like silk, gradually deepens, as if the sunset had been cut into a dress. When the wind blows, the sea of flowers surges, and the golden stamens tremble, releasing a faint fragrance that lures bees and butterflies to swirl around the flower centers in golden vortices. The green peony, in particular, when it first blooms, has tips like jade carvings with a hint of moon white, and when it is in full bloom, it is like an ice wine in an emerald cup, making one suspect it is a divine creation from the Queen Mother's Jade Pool. Occasionally, a petal falls, becoming a rolling agate bead on the embroidered carpet, and even the soil is permeated with the elegant fragrance. Such a captivating beauty is why Liu Yuxi wrote that only the peony is truly the national color, and when it blooms, it moves the entire capital. It uses the entire season's brilliance to interpret the grandeur of being the queen of flowers.", "next_text": "In late spring, the peony garden awakens with layers of petals of the Yao Huang and Wei Zi varieties. When the morning dew has not yet dried, the edges of the petals are glistening with crystal-like droplets, and the inner crimson, like silk, gradually deepens, as if the sunset had been cut into a dress. When the wind blows, the sea of flowers surges, and the golden stamens tremble, releasing a faint fragrance that lures bees and butterflies to swirl around the flower centers in golden vortices. The green peony, in particular, when it first blooms, has tips like jade carvings with a hint of moon white, and when it is in full bloom, it is like an ice wine in an emerald cup, making one suspect it is a divine creation from the Queen Mother's Jade Pool. Occasionally, a petal falls, becoming a rolling agate bead on the embroidered carpet, and even the soil is permeated with the elegant fragrance. Such a captivating beauty is why Liu Yuxi wrote that only the peony is truly the national color, and when it blooms, it moves the entire capital. It uses the entire season's brilliance to interpret the grandeur of being the queen of flowers.", "apply_text_normalization": "auto", "apply_language_text_normalization": true, "latex_read": true, "text_normalization": true, "audio_setting": { "sample_rate": 24000, "bitrate": 32000, "format": "mp3", "channel": 2 }, "timber_weights": [ { "voice_id": "6889b7f4662160e2caad60e9", "weight": 80 }, { "voice_id": "6889b7f3662160e2caad60e8", "weight": 60 }, { "voice_id": "6889b7f3662160e2caad60e7", "weight": 30 }, { "voice_id": "6889b7f2662160e2caad60e6", "weight": 10 } ], "pronunciation_dict": { "tone" : [ "雍容/(yong3)(neng4)", "牡丹/(mu4)(dan3)" ] }, "voice_modify": { "pitch": 50, "intensity": 30, "timbre": -50, "sound_effects": "robotic" }, "subtitle_enable": true } }'; $request = new Request('POST', 'https://openapi.akool.com/api/open/v4/voice/tts', $headers, $body); $res = $client->sendAsync($request)->wait(); echo $res->getBody(); ?> ``` ```python Python theme={null} import requests import json url = "https://openapi.akool.com/api/open/v4/voice/tts" payload = json.dumps({ "input_text": "In late spring, the peony garden awakens with layers of petals of the Yao Huang and Wei Zi varieties. When the morning dew has not yet dried, the edges of the petals are glistening with crystal-like droplets, and the inner crimson, like silk, gradually deepens, as if the sunset had been cut into a dress. When the wind blows, the sea of flowers surges, and the golden stamens tremble, releasing a faint fragrance that lures bees and butterflies to swirl around the flower centers in golden vortices. The green peony, in particular, when it first blooms, has tips like jade carvings with a hint of moon white, and when it is in full bloom, it is like an ice wine in an emerald cup, making one suspect it is a divine creation from the Queen Mother's Jade Pool. Occasionally, a petal falls, becoming a rolling agate bead on the embroidered carpet, and even the soil is permeated with the elegant fragrance. Such a captivating beauty is why Liu Yuxi wrote that only the peony is truly the national color, and when it blooms, it moves the entire capital. It uses the entire season's brilliance to interpret the grandeur of being the queen of flowers.", "voice_id": "6889b628662160e2caad5dbc", "voice_options": { "stability": 0.6, "similarity_boost": 0.8, "style": 1, "speed": 1.0, "speaker_boost": true, "emotion": "happy", "volume": 80 }, "pitch": -5, "webhookUrl": "", "language_code": "zh", "extra_options": { "previous_text": "In late spring, the peony garden awakens with layers of petals of the Yao Huang and Wei Zi varieties. When the morning dew has not yet dried, the edges of the petals are glistening with crystal-like droplets, and the inner crimson, like silk, gradually deepens, as if the sunset had been cut into a dress. When the wind blows, the sea of flowers surges, and the golden stamens tremble, releasing a faint fragrance that lures bees and butterflies to swirl around the flower centers in golden vortices. The green peony, in particular, when it first blooms, has tips like jade carvings with a hint of moon white, and when it is in full bloom, it is like an ice wine in an emerald cup, making one suspect it is a divine creation from the Queen Mother's Jade Pool. Occasionally, a petal falls, becoming a rolling agate bead on the embroidered carpet, and even the soil is permeated with the elegant fragrance. Such a captivating beauty is why Liu Yuxi wrote that only the peony is truly the national color, and when it blooms, it moves the entire capital. It uses the entire season's brilliance to interpret the grandeur of being the queen of flowers.", "next_text": "In late spring, the peony garden awakens with layers of petals of the Yao Huang and Wei Zi varieties. When the morning dew has not yet dried, the edges of the petals are glistening with crystal-like droplets, and the inner crimson, like silk, gradually deepens, as if the sunset had been cut into a dress. When the wind blows, the sea of flowers surges, and the golden stamens tremble, releasing a faint fragrance that lures bees and butterflies to swirl around the flower centers in golden vortices. The green peony, in particular, when it first blooms, has tips like jade carvings with a hint of moon white, and when it is in full bloom, it is like an ice wine in an emerald cup, making one suspect it is a divine creation from the Queen Mother's Jade Pool. Occasionally, a petal falls, becoming a rolling agate bead on the embroidered carpet, and even the soil is permeated with the elegant fragrance. Such a captivating beauty is why Liu Yuxi wrote that only the peony is truly the national color, and when it blooms, it moves the entire capital. It uses the entire season's brilliance to interpret the grandeur of being the queen of flowers.", "apply_text_normalization": "auto", "apply_language_text_normalization": true, "latex_read": true, "text_normalization": true, "audio_setting": { "sample_rate": 24000, "bitrate": 32000, "format": "mp3", "channel": 2 }, "timber_weights": [ { "voice_id": "6889b7f4662160e2caad60e9", "weight": 80 }, { "voice_id": "6889b7f3662160e2caad60e8", "weight": 60 }, { "voice_id": "6889b7f3662160e2caad60e7", "weight": 30 }, { "voice_id": "6889b7f2662160e2caad60e6", "weight": 10 } ], "pronunciation_dict": { "tone" : [ "雍容/(yong3)(neng4)", "牡丹/(mu4)(dan3)" ] }, "voice_modify": { "pitch": 50, "intensity": 30, "timbre": -50, "sound_effects": "robotic" }, "subtitle_enable": true } }) headers = { 'x-api-key':'{{API Key}}', 'Content-Type': 'application/json' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text) ``` **Response** ```json theme={null} { "code": 1000, "msg": "OK", "data": { "create_time": 1751350015709, "uid": 101400, "team_id": "6805fb69e92d9edc7ca0b409", "input_text": "Welcome to the Akool generative AI content creation tool.", "preview": null, "status": 1, "webhookUrl": "", "duration": 0, "file_name": "1ef1d76ebfc244f7a30430f7049d6ebc.mp3", "gender": "Male", "deduction_credit": 1.9295, "name": "27fec311afd743aa889a057e17e93c13", "_id": "68637aff41e5eb74bb8dfe73", "voice_model_id": "686379d641e5eb74bb8dfe3f", "voice_id": "Tq06jbVyFH4l6R-Gjvo_V-p_nVYk5DRrYJZsxeDmlhEtyhcFKKLQODmgngI9llKw", "voice_options": { "stability": 0.7, "similarity_boost": 0.5, "style": 0.6, "speed": 0.8, "speaker_boost": false, "emotion": "happy", "volume": 50 } } } ``` ## Create Voice Changer Only the Akool Multilingual 1 model supports Voice Change. ``` POST https://openapi.akool.com/api/open/v4/voice/change ``` **Request Headers** | **Parameter** | **Value** | **Description** | | ------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | x-api-key | API Key | Your API Key used for request authorization. If both Authorization and x-api-key have values, Authorization will be used first and x-api-key will be discarded. | | Authorization | Bearer `{token}` | Your API Key used for request authorization.[Get Token](/authentication/usage#get-the-token). | **Body Attributes** | **Parameter** | **Type** | **Required** | **Value** | **Description** | | --------------------------- | -------- | ------------ | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | voice\_id | String | true | | Voice ID, get this voice\_id from your cloned voices or akool voice list. [getVoiceId](/ai-tools-suite/voiceLab#get-voice-list) | | source\_voice\_file | String | true | | Audio file URL, supports mp3, mp4, wav, etc. Must be a public accessible URL, The maximum file size is 50MB. | | voice\_options | Object | false | | Audio settings | | - stability | Number | false | | Voice stability (0-1) , Supported voice models: Akool Multilingual 1, [getVoiceModelName](/ai-tools-suite/voiceLab#get-voice-list) | | - similarity\_boost | Number | false | | Similarity boost (0-1) , Supported voice models: Akool Multilingual 1, [getVoiceModelName](/ai-tools-suite/voiceLab#get-voice-list) | | - style | Number | false | | Voice style (0-1) , Supported voice models: Akool Multilingual 1, Akool Multilingual 2. Style examples: cheerful, [getVoiceModelName](/ai-tools-suite/voiceLab#get-voice-list) | | - speaker\_boost | Boolean | false | | Speaker boost, Supported voice models: Akool Multilingual 1, [getVoiceModelName](/ai-tools-suite/voiceLab#get-voice-list) | | - file\_format | String | false | mp3 | File format, supports mp3 and wav formats. | | - remove\_background\_noise | Boolean | false | false | Remove background noise, disabled by default | | - speed | Number | false | 1 | Controls the speed of generated audio, default value is 1, available range \[0.7, 1.2]. | | webhookUrl | String | false | | Callback url address based on HTTP request | | voice\_model\_name | String | false | | The designated model for Clone, Supported voice models: Akool Multilingual 1. [getVoiceModelName](/ai-tools-suite/voiceLab#get-voice-list) | **Response Attributes** | **Parameter** | **Type** | **Value** | **Description** | | --------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | code | int | 1000 | Interface returns business status code(1000:success) | | msg | String | | Interface returns status information | | data | Object | | Response data object | | - create\_time | Long | 1751350363707 | Creation timestamp | | - uid | Integer | 101400 | User ID | | - team\_id | String | "6805fb69e92d9edc7ca0b409" | Team ID | | - preview | String | null | Generated audio URL, this value will be updated after task completion, you can view it in the resourceList. [Get Resource List](/ai-tools-suite/voiceLab#get-voice-results-list) | | - source\_voice\_file | String | "[https://drz0f01yeq1cx.cloudfront.net/1749098405491-5858-1749019840512audio.mp3](https://drz0f01yeq1cx.cloudfront.net/1749098405491-5858-1749019840512audio.mp3)" | Original audio file URL | | - status | Integer |

1

| Voice changer status: 【1:queueing, 2:processing, 3:completed, 4:failed】 | | - webhookUrl | String |

""

| Callback URL | | - duration | Integer |

12800

| Audio duration in milliseconds | | - file\_name | String |

"1749098405491-5858-1749019840512audio.mp3"

| Generated file name | | - gender | String |

"Female"

| Voice gender | | - deduction\_credit | Float |

0.512

| Deducted credits | | - name | String |

"3f591fc370c542fca9087f124b5ad82b"

| Generated name | | - \_id | String |

"68637c5b41e5eb74bb8dfec6"

| Document ID | | - voice\_model\_id | String |

"67a45479354b7c1fff7e943a"

| Voice document ID | | - voice\_id | String |

"hkfHEbBvdQFNX4uWHqRF"

| Voice ID | | - voice\_options | Object | | Voice options object | | - stability | Number |

0.7

| Voice stability setting | | - similarity\_boost | Number |

0.5

| Similarity boost setting | | - style | Number |

0.6

| Voice style setting | | - speaker\_boost | Boolean |

false

| Speaker boost setting | ### Example **Body** ```json theme={null} { "voice_id": "6889b628662160e2caad5dbc", "source_voice_file": "https://drz0f01yeq1cx.cloudfront.net/1749098405491-5858-1749019840512audio.mp3", "voice_options": { "stability": 0.9, "similarity_boost": 0.7, "style": 1, "speaker_boost": false, "remove_background_noise": true, "speed": 1, "file_format": "mp3" }, "voice_model_name": "Akool Multilingual 1", "webhookUrl": "" } ``` **Request** ```bash cURL theme={null} curl --location 'https://openapi.akool.com/api/open/v4/voice/change' \ --header 'x-api-key: {{API Key}}' \ --header 'Content-Type: application/json' \ --data '{ "voice_id": "6889b628662160e2caad5dbc", "source_voice_file": "https://drz0f01yeq1cx.cloudfront.net/1749098405491-5858-1749019840512audio.mp3", "voice_options": { "stability": 0.9, "similarity_boost": 0.7, "style": 1, "speaker_boost": false, "remove_background_noise": true, "speed": 1, "file_format": "mp3" }, "voice_model_name": "Akool Multilingual 1", "webhookUrl": "" }' ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, "{\n \"voice_id\": \"6889b628662160e2caad5dbc\",\n \"source_voice_file\": \"https://drz0f01yeq1cx.cloudfront.net/1749098405491-5858-1749019840512audio.mp3\",\n \"voice_options\": {\n \"stability\": 0.9,\n \"similarity_boost\": 0.7,\n \"style\": 1,\n \"speaker_boost\": false,\n \"remove_background_noise\": true,\n \"speed\": 1,\n \"file_format\": \"mp3\"\n },\n \"voice_model_name\": \"Akool Multilingual 1\",\n \"webhookUrl\": \"\"\n}"); Request request = new Request.Builder() .url("https://openapi.akool.com/api/open/v4/voice/change") .method("POST", body) .addHeader("x-api-key", "{{API Key}}") .addHeader("Content-Type", "application/json") .build(); Response response = client.newCall(request).execute(); ``` ```js Javascript theme={null} const myHeaders = new Headers(); myHeaders.append("x-api-key", "{{API Key}}"); myHeaders.append("Content-Type", "application/json"); const raw = JSON.stringify({ "voice_id": "6889b628662160e2caad5dbc", "source_voice_file": "https://drz0f01yeq1cx.cloudfront.net/1749098405491-5858-1749019840512audio.mp3", "voice_options": { "stability": 0.9, "similarity_boost": 0.7, "style": 1, "speaker_boost": false, "remove_background_noise": true, "speed": 1, "file_format": "mp3" }, "voice_model_name": "Akool Multilingual 1", "webhookUrl": "" }); const requestOptions = { method: "POST", headers: myHeaders, body: raw, redirect: "follow" }; fetch("https://openapi.akool.com/api/open/v4/voice/change", requestOptions) .then((response) => response.text()) .then((result) => console.log(result)) .catch((error) => console.error(error)); ``` ```php PHP theme={null} '{{API Key}}', 'Content-Type' => 'application/json' ]; $body = '{ "voice_id": "6889b628662160e2caad5dbc", "source_voice_file": "https://drz0f01yeq1cx.cloudfront.net/1749098405491-5858-1749019840512audio.mp3", "voice_options": { "stability": 0.9, "similarity_boost": 0.7, "style": 1, "speaker_boost": false, "remove_background_noise": true, "speed": 1, "file_format": "mp3" }, "voice_model_name": "Akool Multilingual 1", "webhookUrl": "" }'; $request = new Request('POST', 'https://openapi.akool.com/api/open/v4/voice/change', $headers, $body); $res = $client->sendAsync($request)->wait(); echo $res->getBody(); ?> ``` ```python Python theme={null} import requests import json url = "https://openapi.akool.com/api/open/v4/voice/change" payload = json.dumps({ "voice_id": "6889b628662160e2caad5dbc", "source_voice_file": "https://drz0f01yeq1cx.cloudfront.net/1749098405491-5858-1749019840512audio.mp3", "voice_options": { "stability": 0.9, "similarity_boost": 0.7, "style": 1, "speaker_boost": false, "remove_background_noise": true, "speed": 1, "file_format": "mp3" }, "voice_model_name": "Akool Multilingual 1", "webhookUrl": "" }) headers = { 'x-api-key':'{{API Key}}', 'Content-Type': 'application/json' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text) ``` **Response** ```json theme={null} { "code": 1000, "msg": "OK", "data": { "create_time": 1751350363707, "uid": 101400, "team_id": "6805fb69e92d9edc7ca0b409", "source_voice_file": "https://drz0f01yeq1cx.cloudfront.net/1749098405491-5858-1749019840512audio.mp3", "preview": null, "status": 1, "webhookUrl": "", "duration": 12800, "file_name": "1749098405491-5858-1749019840512audio.mp3", "gender": "Female", "deduction_credit": 0.512, "name": "3f591fc370c542fca9087f124b5ad82b", "_id": "68637c5b41e5eb74bb8dfec6", "voice_model_id": "67a45479354b7c1fff7e943a", "voice_id": "hkfHEbBvdQFNX4uWHqRF", "voice_options": { "stability": 0.7, "similarity_boost": 0.5, "style": 0.6, "speaker_boost": false } } } ``` ## Get Voice Results List ``` GET https://openapi.akool.com/api/open/v4/voice/resource/list ``` **Request Headers** | **Parameter** | **Value** | **Description** | | ------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | x-api-key | API Key | Your API Key used for request authorization. If both Authorization and x-api-key have values, Authorization will be used first and x-api-key will be discarded. | | Authorization | Bearer `{token}` | Your API Key used for request authorization.[Get Token](/authentication/usage#get-the-token). | **Query Attributes** | **Parameter** | **Type** | **Required** | **Value** | **Description** | | ------------- | -------- | ------------ | --------- | -------------------------- | | type | String | true | 1,2 | 1-voiceTTS, 2-voiceChanger | | page | String | false | 1 | Page number | | size | String | false | 10 | Page size | **Response Attributes** | **Parameter** | **Type** | **Value** | **Description** | | -------------------- | -------- | ------------------------------------------------------------------------------------------- | --------------------------------------------------------- | | code | Integer |

1000

| API returns status code(1000:success) | | msg | String | | API returns status message | | data | Object | | Response data object | | - result | Array | | Voice resource list | | -- \_id | String |

"68637c5b41e5eb74bb8dfec6"

| Document ID | | -- create\_time | Long |

1751350363707

| Creation timestamp | | -- update\_time | Long |

1751350368468

| Update timestamp | | -- uid | Integer |

101400

| User ID | | -- team\_id | String |

"6805fb69e92d9edc7ca0b409"

| Team ID | | -- rate | String |

"100%"

| Processing rate | | -- preview | String | "[https://drz0f01yeq1cx.cloudfront.net/](https://drz0f01yeq1cx.cloudfront.net/)..." | Generated audio URL | | -- status | Integer |

3

| Status: 【1:queueing, 2:processing, 3:completed, 4:failed】 | | -- webhookUrl | String |

""

| Callback URL | | -- duration | Integer |

12852

| Audio duration in milliseconds | | -- file\_name | String |

"1749098405491-5858-1749019840512audio.mp3"

| File name | | -- gender | String |

"Female"

| Voice gender | | -- deduction\_credit | Float |

0.9295

| Deducted credits | | -- name | String |

"3f591fc370c542fca9087f124b5ad82b"

| Resource name | | -- input\_text | String |

"Słyszę, że chcesz leżeć płasko? Gratulacje — przynajmniej zrozumiałeś grawitację! "

| Text to Speech trial listening text | | -- \_\_v | Integer |

0

| Version number | | - count | Integer |

1

| Total count of resources | | - page | Integer |

1

| Current page number | | - size | Integer |

10

| Page size | ### Example **Request** ```bash cURL theme={null} curl --location 'https://openapi.akool.com/api/open/v4/voice/resource/list?type=1&page=1&size=10' \ --header 'x-api-key: {{API Key}}' ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("text/plain"); RequestBody body = RequestBody.create(mediaType, ""); Request request = new Request.Builder() .url("https://openapi.akool.com/api/open/v4/voice/resource/list?type=1&page=1&size=10") .method("GET", body) .addHeader("x-api-key", "{{API Key}}") .build(); Response response = client.newCall(request).execute(); ``` ```js Javascript theme={null} const myHeaders = new Headers(); myHeaders.append("x-api-key", "{{API Key}}"); const requestOptions = { method: "GET", headers: myHeaders, redirect: "follow" }; fetch("https://openapi.akool.com/api/open/v4/voice/resource/list?type=1&page=1&size=10", requestOptions) .then((response) => response.text()) .then((result) => console.log(result)) .catch((error) => console.error(error)); ``` ```php PHP theme={null} '{{API Key}}' ]; $request = new Request('GET', 'https://openapi.akool.com/api/open/v4/voice/resource/list?type=1&page=1&size=10', $headers); $res = $client->sendAsync($request)->wait(); echo $res->getBody(); ?> ``` ```python Python theme={null} import requests url = "https://openapi.akool.com/api/open/v4/voice/resource/list?type=1&page=1&size=10" payload = {} headers = { 'x-api-key':'{{API Key}}' } response = requests.request("GET", url, headers=headers, data=payload) print(response.text) ``` **Response** ```json theme={null} { "code": 1000, "msg": "OK", "data": { "result": [ { "_id": "68637c5b41e5eb74bb8dfec6", "create_time": 1751350363707, "update_time": 1751350368468, "uid": 101400, "team_id": "6805fb69e92d9edc7ca0b409", "rate": "100%", "preview": "https://drz0f01yeq1cx.cloudfront.net/1751350368172-audio.mp3", "status": 3, "webhookUrl": "", "duration": 12852, "file_name": "1749098405491-5858-1749019840512audio.mp3", "gender": "Female", "deduction_credit": 0.9295, "name": "3f591fc370c542fca9087f124b5ad82b", "input_text": "Słyszę, że chcesz leżeć płasko? Gratulacje — przynajmniej zrozumiałeś grawitację! ", "__v": 0 } ], "count": 1, "page": 1, "size": 10 } } ``` ## Get Voice List ``` GET https://openapi.akool.com/api/open/v4/voice/list ``` **Request Headers** | **Parameter** | **Value** | **Description** | | ------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | x-api-key | API Key | Your API Key used for request authorization. If both Authorization and x-api-key have values, Authorization will be used first and x-api-key will be discarded. | | Authorization | Bearer `{token}` | Your API Key used for request authorization.[Get Token](/authentication/usage#get-the-token). | **Query Attributes** | **Parameter** | **Type** | **Required** | **Value** | **Description** | | --------------- | -------- | ------------ | ------------------------------ | ---------------------------------------------------------------- | | type | String | true |

1,2

| 1-VoiceClone, 2-Akool Voices | | page | String | false |

1

| Page number | | size | String | false |

10

| Page size | | style | String | false |

Calm,Authoritative

| Voice style filters, separated by commas | | gender | String | false |

Male,Female

| Gender filters, separated by commas | | age | String | false |

Young,Middle,Elderly

| Age filters, separated by commas | | scenario | String | false |

Advertisement,Education

| Scenario filters, separated by commas | | name | String | false |

MyVoice

| Voice name, supports fuzzy search | | support\_stream | Integer | false |

1

| 2-Voice does not support streaming.; 1-Voice supports streaming. | **Response Attributes** | **Parameter** | **Type** | **Value** | **Description** | | --------------------- | -------- | -------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | | code | Integer |

1000

| API returns status code(1000:success) | | msg | String | | API returns status message | | data | Object | | Response data object | | - result | Array | | Voice list | | -- \_id | String |

"68676e544439e3b8e246a077"

| Document ID | | -- uid | Integer |

101400

| User ID | | -- team\_id | String |

"6805fb69e92d9edc7ca0b409"

| Team ID | | -- voice\_id | String |

"zQAGCFElz23u6Brdj4L-NrbEmSxswXdoPN\_GBpYgUPHo1EGWgZgAnFJexONx\_jGy"

| Voice ID | | -- gender | String |

"Male"

| Voice gender | | -- language | String |

"Polish"

| Voice language | | -- locale | String |

"pl"

| Voice locale | | -- name | String |

"MyVoice0626-01"

| Voice name | | -- preview | String |

"[https://d2qf6ukcym4kn9.cloudfront.net/](https://d2qf6ukcym4kn9.cloudfront.net/)..."

| Preview audio URL | | -- text | String |

"This is a comic style model..."

| Preview text content | | -- duration | Integer |

9822

| Audio duration in milliseconds | | -- status | Integer |

3

| Voice status: 【1:queueing, 2:processing, 3:completed, 4:failed】 | | -- create\_time | Long |

1751608916162

| Creation timestamp | | -- update\_time | Long |

1751608916162

| Update timestamp | | -- style | Array |

\["Authoritative", "Calm"]

| Voice style tags | | -- scenario | Array |

\["Advertisement"]

| Scenario tags | | -- age | Array |

\["Elderly", "Middle"]

| Age tags | | -- deduction\_credit | Integer |

0

| Deducted credits | | -- webhookUrl | String |

""

| Callback URL | | -- voice\_model\_name | String |

"Akool Multilingual 3"

| Supported voice model name | | -- support\_stream | Boolean |

true

| Supported stream: true/false, Akool Multilingual 1 & Akool Multilingual 3 only support stream. | | - count | Integer |

9

| Total count of voices | | - page | Integer |

1

| Current page number | | - size | Integer |

1

| Page size | ### Example **Request** ```bash cURL theme={null} curl --location 'https://openapi.akool.com/api/open/v4/voice/list?type=1&page=1&size=10&style=Calm,Authoritative&gender=Male&name=MyVoice' \ --header 'x-api-key: {{API Key}}' ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("text/plain"); RequestBody body = RequestBody.create(mediaType, ""); Request request = new Request.Builder() .url("https://openapi.akool.com/api/open/v4/voice/list?type=1&page=1&size=10&style=Calm,Authoritative&gender=Male&name=MyVoice") .method("GET", body) .addHeader("x-api-key", "{{API Key}}") .build(); Response response = client.newCall(request).execute(); ``` ```js Javascript theme={null} const myHeaders = new Headers(); myHeaders.append("x-api-key", "{{API Key}}"); const requestOptions = { method: "GET", headers: myHeaders, redirect: "follow" }; fetch("https://openapi.akool.com/api/open/v4/voice/list?type=1&page=1&size=10&style=Calm,Authoritative&gender=Male&name=MyVoice", requestOptions) .then((response) => response.text()) .then((result) => console.log(result)) .catch((error) => console.error(error)); ``` ```php PHP theme={null} '{{API Key}}' ]; $request = new Request('GET', 'https://openapi.akool.com/api/open/v4/voice/list?type=1&page=1&size=10&style=Calm,Authoritative&gender=Male&name=MyVoice', $headers); $res = $client->sendAsync($request)->wait(); echo $res->getBody(); ?> ``` ```python Python theme={null} import requests url = "https://openapi.akool.com/api/open/v4/voice/list" payload = {} headers = { 'x-api-key':'{{API Key}}' } params = { 'type': '1', 'page': '1', 'size': '10', 'style': 'Calm,Authoritative', 'gender': 'Male', 'name': 'MyVoice' } response = requests.request("GET", url, headers=headers, data=payload, params=params) print(response.text) ``` **Response** ```json theme={null} { "code": 1000, "msg": "OK", "data": { "result": [ { "_id": "68676e544439e3b8e246a077", "uid": 101400, "team_id": "6805fb69e92d9edc7ca0b409", "voice_id": "zQAGCFElz23u6Brdj4L-NrbEmSxswXdoPN_GBpYgUPHo1EGWgZgAnFJexONx_jGy", "gender": "Male", "language": "Polish", "locale": "pl", "name": "MyVoice0626-01", "preview": "https://d2qf6ukcym4kn9.cloudfront.net/1751608955706-c1cf1692-fd47-417c-b18a-dcbbb93360fa-2756.mp3", "text": "This is a comic style model, this is a comic style model, this is a comic style model, this is a comic style model", "duration": 9822, "status": 3, "create_time": 1751608916162, "style": [ "Authoritative", "Calm" ], "scenario": [ "Advertisement" ], "age": [ "Elderly", "Middle" ], "deduction_credit": 0, "webhookUrl": "", "voice_model_name": "Akool Multilingual 3", "support_stream": true } ], "count": 9, "page": 1, "size": 1 } } ``` ## Delete Voice ``` POST https://openapi.akool.com/api/open/v4/voice/del ``` **Request Headers** | **Parameter** | **Value** | **Description** | | ------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | x-api-key | API Key | Your API Key used for request authorization. If both Authorization and x-api-key have values, Authorization will be used first and x-api-key will be discarded. | | Authorization | Bearer `{token}` | Your API Key used for request authorization.[Get Token](/authentication/usage#get-the-token). | **Body Attributes** | **Parameter** | **Type** | **Required** | **Value** | **Description** | | ------------- | -------- | ------------ | --------- | ---------------------------------------------------------------------------------------- | | \_ids | Array | true | | Voice list document IDs [Get Voice Document ID](/ai-tools-suite/voiceLab#get-voice-list) | **Response Attributes** | **Parameter** | **Type** | **Value** | **Description** | | -------------------- | -------- | ---------------------------------------------------------- | ------------------------------------- | | code | integer |

1000

| API returns status code(1000:success) | | msg | String | | API returns status message | | data | Object | | Response data object | | - successIds | Array | | Deleted voice document IDs | | - noPermissionVoices | Array | | Delete failed voice document msg list | | - \_id | String |

6881cd86618fa41c89557b0c

| Delete failed voice document ID | | - msg | String |

VoiceId:6881cd86618fa41c89557b0c resource not found

| Delete failed voice error msg | ### Example **Body** ```json theme={null} { "_ids": [ "6836b8183a59f36196bb9c52", "6836ba935026505ab7a529ce" ] } ``` **Request** ```bash cURL theme={null} curl --location --request POST 'https://openapi.akool.com/api/open/v4/voice/del' \ --header 'x-api-key: {{API Key}}' \ --header 'Content-Type: application/json' \ --data '{ "_ids": [ "6836b8183a59f36196bb9c52", "6836ba935026505ab7a529ce" ] }' ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, "{\n \"_ids\": [\n \"6836b8183a59f36196bb9c52\",\n \"6836ba935026505ab7a529ce\"\n ]\n}"); Request request = new Request.Builder() .url("https://openapi.akool.com/api/open/v4/voice/del") .method("POST", body) .addHeader("x-api-key", "{{API Key}}") .addHeader("Content-Type", "application/json") .build(); Response response = client.newCall(request).execute(); ``` ```js Javascript theme={null} const myHeaders = new Headers(); myHeaders.append("x-api-key", "{{API Key}}"); myHeaders.append("Content-Type", "application/json"); const raw = JSON.stringify({ "_ids": [ "6836b8183a59f36196bb9c52", "6836ba935026505ab7a529ce" ] }); const requestOptions = { method: "POST", headers: myHeaders, body: raw, redirect: "follow" }; fetch("https://openapi.akool.com/api/open/v4/voice/del", requestOptions) .then((response) => response.text()) .then((result) => console.log(result)) .catch((error) => console.error(error)); ``` ```php PHP theme={null} '{{API Key}}', 'Content-Type' => 'application/json' ]; $body = '{ "_ids": [ "6836b8183a59f36196bb9c52", "6836ba935026505ab7a529ce" ] }'; $request = new Request('POST', 'https://openapi.akool.com/api/open/v4/voice/del', $headers, $body); $res = $client->sendAsync($request)->wait(); echo $res->getBody(); ?> ``` ```python Python theme={null} import requests import json url = "https://openapi.akool.com/api/open/v4/voice/del" payload = json.dumps({ "_ids": [ "6836b8183a59f36196bb9c52", "6836ba935026505ab7a529ce" ] }) headers = { 'x-api-key':'{{API Key}}', 'Content-Type': 'application/json' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text) ``` **Response** ```json theme={null} { "code": 1000, "msg": "Delete voice successfully", "data": { "successIds": [ "6882f4c10529ae771e71531d" ], "noPermissionVoices": [ { "_id": "6881cd86618fa41c89557b0c", "msg": "VoiceId:6881cd86618fa41c89557b0c resource not found" } ] } } ``` ## Get Voice Detail ``` GET https://openapi.akool.com/api/open/v4/voice/detail/{_id} ``` **Request Headers** | **Parameter** | **Value** | **Description** | | ------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | x-api-key | API Key | Your API Key used for request authorization. If both Authorization and x-api-key have values, Authorization will be used first and x-api-key will be discarded. | | Authorization | Bearer `{token}` | Your API Key used for request authorization.[Get Token](/authentication/usage#get-the-token). | **Path Attributes** | **Parameter** | **Type** | **Required** | **Value** | **Description** | | ------------- | -------- | ------------ | --------- | ---------------------------------------------------------------------------------------- | | \_id | String | true | | Voice list document IDs [Get Voice Document ID](/ai-tools-suite/voiceLab#get-voice-list) | **Response Attributes** | **Parameter** | **Type** | **Value** | **Description** | | -------------------- | -------- | ----------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | | code | Integer |

1000

| API returns status code(1000:success) | | msg | String | | API returns status message | | data | Object | | Response data object | | - \_id | String |

"6836bafb5026505ab7a529fa"

| Document ID | | - uid | Integer |

101400

| User ID | | - team\_id | String |

"6805fb69e92d9edc7ca0b409"

| Team ID | | - voice\_id | String |

"yRBw4OM8YFm5pCNKxJQ7"

| Voice ID | | - gender | String |

"Male"

| Voice gender | | - name | String |

"Snow Peak 01"

| Voice name | | - preview | String | "[https://drz0f01yeq1cx.cloudfront.net/](https://drz0f01yeq1cx.cloudfront.net/)..." | Preview audio URL | | - text | String | "Hello, I'm your personalized AI voice..." | Preview text content | | - duration | Integer |

7055

| Audio duration in milliseconds | | - status | Integer |

3

| Voice status: 【1:queueing, 2:processing, 3:completed, 4:failed】 | | - create\_time | Long |

1748417275493

| Creation timestamp | | - style | Array |

\["Authoritative", "Calm"]

| Voice style tags | | - scenario | Array |

\["Advertisement"]

| Scenario tags | | - age | Array |

\["Elderly", "Middle"]

| Age tags | | - deduction\_credit | Integer |

0

| Deducted credits | | - voice\_model\_name | String |

"Akool Multilingual 1"

| Supported voice model name | | - support\_stream | Boolean |

true

| Supported stream: true/false, Akool Multilingual 1 & Akool Multilingual 3 only support stream. | | - language | String |

"Chinese"

| Voice language | | - locale | String |

"zh"

| Voice locale | | - update\_time | Long |

1751608916162

| Update timestamp | ### Example **Request** ```bash cURL theme={null} curl --location 'https://openapi.akool.com/api/open/v4/voice/detail/6836bafb5026505ab7a529fa' \ --header 'x-api-key: {{API Key}}' ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("text/plain"); RequestBody body = RequestBody.create(mediaType, ""); Request request = new Request.Builder() .url("https://openapi.akool.com/api/open/v4/voice/detail/6836bafb5026505ab7a529fa") .method("GET", body) .addHeader("x-api-key", "{{API Key}}") .build(); Response response = client.newCall(request).execute(); ``` ```js Javascript theme={null} const myHeaders = new Headers(); myHeaders.append("x-api-key", "{{API Key}}"); const requestOptions = { method: "GET", headers: myHeaders, redirect: "follow" }; fetch("https://openapi.akool.com/api/open/v4/voice/detail/6836bafb5026505ab7a529fa", requestOptions) .then((response) => response.text()) .then((result) => console.log(result)) .catch((error) => console.error(error)); ``` ```php PHP theme={null} '{{API Key}}' ]; $request = new Request('GET', 'https://openapi.akool.com/api/open/v4/voice/detail/6836bafb5026505ab7a529fa', $headers); $res = $client->sendAsync($request)->wait(); echo $res->getBody(); ?> ``` ```python Python theme={null} import requests url = "https://openapi.akool.com/api/open/v4/voice/detail/6836bafb5026505ab7a529fa" payload = {} headers = { 'x-api-key':'{{API Key}}' } response = requests.request("GET", url, headers=headers, data=payload) print(response.text) ``` **Response** ```json theme={null} { "code": 1000, "msg": "OK", "data": { "_id": "6882f23c0529ae771e7152dc", "uid": 101400, "team_id": "6805fb69e92d9edc7ca0b409", "voice_id": "kfr_1wGPuauzcSOZgpBGLd_ApviIHqMIZ5bS2OeMiMkvId0eAMkq1ii8rvInZ2pE", "gender": "Male", "name": "zhongwen-072501", "preview": "https://drz0f01yeq1cx.cloudfront.net/1753412190380-sample.mp3", "text": "人生就像登山,重要的不是顶峰的高度,而是攀登时的姿态。当你觉得脚步沉重时,请记住:竹子用四年时间仅生长3厘米,但从第五年开始,每天以30厘米的速度疯长。那些看似微不足道的积累,终将在某个转角绽放光芒。前路或许泥泞,但每个坚持的脚印都在书写传奇;黑夜也许漫长,但晨光总在咬牙坚持后准时降临。正如海明威所说:人可以被毁灭,但不能被打败。2025年的今天,愿你把挫折当作垫脚石,让汗水成为勋章,因为这个世界永远奖励那些在跌倒后依然选择起身奔跑的人。", "duration": 55353, "status": 3, "create_time": 1753412156588, "style": [ "Authoritative", "Calm" ], "scenario": [ "Advertisenment" ], "age": [ "Elderly", "Middle" ], "deduction_credit": 0, "webhookUrl": "", "language": "Chinese", "locale": "zh", "voice_model_name": "Akool Multilingual 3", "support_stream": true } } ``` ## Get Voice Result Detail ``` GET https://openapi.akool.com/api/open/v4/voice/resource/detail/{_id} ``` **Request Headers** | **Parameter** | **Value** | **Description** | | ------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | x-api-key | API Key | Your API Key used for request authorization. If both Authorization and x-api-key have values, Authorization will be used first and x-api-key will be discarded. | | Authorization | Bearer `{token}` | Your API Key used for request authorization.[Get Token](/authentication/usage#get-the-token). | **Path Attributes** | **Parameter** | **Type** | **Required** | **Value** | **Description** | | ------------- | -------- | ------------ | --------- | ----------------------------------------------------------------------------------------------- | | \_id | String | true | | Voice result document ID [Get Voice Result ID](/ai-tools-suite/voiceLab#get-voice-results-list) | **Response Attributes** | **Parameter** | **Type** | **Value** | **Description** | | -------------------- | -------- | ----------------------------------------- | --------------------------------------------------------- | | code | Integer |

1000

| API returns status code(1000:success) | | msg | String | | API returns status message | | data | Object | | Response data object | | - result | Object | | Voice result object | | -- \_id | String |

"688afbd9d2b4b269d1123ffb"

| Document ID | | -- create\_time | Long |

1753938905005

| Creation timestamp | | -- update\_time | Long |

0

| Update timestamp | | -- uid | Integer |

101400

| User ID | | -- team\_id | String |

"6805fb69e92d9edc7ca0b409"

| Team ID | | -- input\_text | String | "Życie jak wspinaczka górska..." | Input text content | | -- rate | String |

"100%"

| Processing rate | | -- status | Integer |

1

| Status: 【1:queueing, 2:processing, 3:completed, 4:failed】 | | -- webhookUrl | String |

""

| Callback URL | | -- duration | Integer |

0

| Audio duration in milliseconds | | -- file\_name | String |

"1753938905005.mp3"

| File name | | -- gender | String |

"Male"

| Voice gender | | -- deduction\_credit | Float |

0.5148

| Deducted credits | | -- name | String |

"26ca668a9eb448b7b9a3806fa86207f3"

| Resource name | | -- priority | Integer |

2

| Priority level | | -- language\_code | String |

"pt"

| Language code | | -- \_\_v | Integer |

0

| Version number | | -- preview | String |

null

| Preview audio URL | ### Example **Request** ```bash cURL theme={null} curl --location 'https://openapi.akool.com/api/open/v4/voice/resource/detail/688afbd9d2b4b269d1123ffb' \ --header 'x-api-key: {{API Key}}' ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("text/plain"); RequestBody body = RequestBody.create(mediaType, ""); Request request = new Request.Builder() .url("https://openapi.akool.com/api/open/v4/voice/resource/detail/688afbd9d2b4b269d1123ffb") .method("GET", body) .addHeader("x-api-key", "{{API Key}}") .build(); Response response = client.newCall(request).execute(); ``` ```js Javascript theme={null} const myHeaders = new Headers(); myHeaders.append("x-api-key", "{{API Key}}"); const requestOptions = { method: "GET", headers: myHeaders, redirect: "follow" }; fetch("https://openapi.akool.com/api/open/v4/voice/resource/detail/688afbd9d2b4b269d1123ffb", requestOptions) .then((response) => response.text()) .then((result) => console.log(result)) .catch((error) => console.error(error)); ``` ```php PHP theme={null} '{{API Key}}' ]; $request = new Request('GET', 'https://openapi.akool.com/api/open/v4/voice/resource/detail/688afbd9d2b4b269d1123ffb', $headers); $res = $client->sendAsync($request)->wait(); echo $res->getBody(); ?> ``` ```python Python theme={null} import requests url = "https://openapi.akool.com/api/open/v4/voice/resource/detail/688afbd9d2b4b269d1123ffb" payload = {} headers = { 'x-api-key':'{{API Key}}' } response = requests.request("GET", url, headers=headers, data=payload) print(response.text) ``` **Response** ```json theme={null} { "code": 1000, "msg": "OK", "data": { "result": { "_id": "688afbd9d2b4b269d1123ffb", "create_time": 1753938905005, "update_time": 0, "uid": 101400, "team_id": "6805fb69e92d9edc7ca0b409", "input_text": "Życie jak wspinaczka górska: ważniejsza od wysokości szczytu jest postawa, z jaką się wspinasz. Gdy czujesz, że stopy", "rate": "100%", "status": 1, "webhookUrl": "", "duration": 0, "file_name": "1753938905005.mp3", "gender": "Male", "deduction_credit": 0.5148, "name": "26ca668a9eb448b7b9a3806fa86207f3", "priority": 2, "language_code": "pt", "__v": 0, "preview": null } } } ``` # Webhook Source: https://docs.akool.com/ai-tools-suite/webhook **A webhook is an HTTP-based callback function that allows lightweight, event-driven communication between 2 application programming interfaces (APIs). Webhooks are used by a wide variety of web apps to receive small amounts of data from other apps。** **Response Data(That is the response data that webhookUrl in the request parameter needs to give us)** If success, http statusCode it must be 200 * **statusCode** is the http status of response to your request . If success,it must be **200**. If you do not return a status code value of 200, we will retry the response to your webhook address. **Response Data(The response result we give to the webhookUrl)** **Content-Type: application/json** **Response Attributes** | **Parameter** | **Type** | **Value** | **Description** | | ------------- | -------- | --------- | ------------------------------------------------------------------------------------------------ | | signature | String | | message body signature: signature =sha1(sort(clientId、timestamp、nonce, dataEncrypt)) | | dataEncrypt | String | | message body encryption, need decryption processing is required to obtain the real response data | | timestamp | Number | | | | nonce | String | | | ```json theme={null} { "signature": "04e30dd43d9d8f95dd7c127dad617f0929d61c1d", "dataEncrypt": "LuG1OVSVIwOO/xpW00eSYo77Ncxa9h4VKmOJRjwoyoAmCIS/8FdJRJ+BpZn90BVAAg8xpU1bMmcDlAYDT010Wa9tNi1jivX25Ld03iA4EKs=", "timestamp": 1710757981609, "nonce": "1529" } ``` When we complete the signature checksum and dataEncrypt decryption, we can get the real response content. The decrypted content of dataEncrypt is: | **Parameter** | **Type** | **Value** | **Description** | | ------------- | -------- | -------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | | \_id | String | | \_id: returned by each interface | | status | Number | 2 or 3 or 4 | status: the status of image or video or faceswap or background change or avatar or audio: 【1:queueing, 2:processing,3:completed, 4:failed】 | | type | String | faceswap or image or audio or talking photo or video translate or background change or avatar or lipsync | Distinguish the type of each interface | | url | String | | when staus = 3, the url is the final result about audio, image, and video. | **Next, we will introduce the process and methods of encryption and decryption.** ### Encryption and Decryption technology solution The encryption and decryption technical solution is implemented based on the AES encryption and decryption algorithm, as follows: 1. clientSecret: This is the message encryption and decryption Key. The length is fixed at 24 characters. ClientSecret is used as the encryption key. The clientSecret is the API Key displayed on the Website API Keys page. 2. AES adopts CBC mode, the secret key length is 24 bytes (192 bits), and the data is filled with PKCS#7; PKCS#7: K is the number of bytes of the secret key (24 is used), Buf is the content to be encrypted, N is its number of bytes. Buf needs to be filled to an integer multiple of K. Fill (K - N%K) bytes at the end of Buf, and the content of each byte is (K - N%K). 3. The IV length of AES is 16 bytes, and clientId is used as the IV. **Message body encryption** dataEncrypt is the result of the platform encrypting the message as follows: * dataEncrypt = AES\_Encrypt( data, clientId, clientSecret ) Among them, data is the body content we need to transmit, clientId is the initial vector, and clientSecret is the encryption key. **Message body signature** In order to verify the legitimacy of the message body, developers can verify the authenticity of the message body and decrypt the message body that passes the verification. Specific method: dataSignature=sha1(sort(clientId、timestamp、nonce, dataEncrypt)) | **Parameter** | **Description** | | ------------- | ---------------------------------------------------------- | | clientId | clientId of user key pair | | timestamp | timestamp in body | | nonce | nonce in body | | dataEncrypt | The previous article describes the ciphertext message body | **Message body verification and decryption** The developer first verifies the correctness of the message body signature, and then decrypts the message body after passing the verification. **Ways of identifying:** 1. The developer calculates the signature,compareSignature=sha1(sort(clientId、timestamp、nonce, dataEncrypt)) 2. Compare compareSignature and the signature in the body to see if they are equal. If they are equal, the verification is passed. The decryption method is as follows: * data = AES\_Decrypt(dataEncrypt, clientSecret); **Example: Encryption and Decryption** 1. To use nodejs or python or java for encryption. ```javascript Nodejs theme={null} // To use nodejs for encryption, you need to install crypto-js. Use the command npm install crypto-js to install it. const CryptoJS = require('crypto-js') const crypto = require('crypto'); // Generate signature function generateMsgSignature(clientId, timestamp, nonce, msgEncrypt){ const sortedStr = [clientId, timestamp, nonce, msgEncrypt].sort().join(''); const hash = crypto.createHash('sha1').update(sortedStr).digest('hex'); return hash; } // decryption algorithm function generateAesDecrypt(dataEncrypt,clientId,clientSecret){ const aesKey = clientSecret const key = CryptoJS.enc.Utf8.parse(aesKey) const iv = CryptoJS.enc.Utf8.parse(clientId) const decrypted = CryptoJS.AES.decrypt(dataEncrypt, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }) return decrypted.toString(CryptoJS.enc.Utf8) } // Encryption Algorithm function generateAesEncrypt(data,clientId,clientSecret){ const aesKey = clientSecret const key = CryptoJS.enc.Utf8.parse(aesKey) const iv = CryptoJS.enc.Utf8.parse(clientId) const srcs = CryptoJS.enc.Utf8.parse(data) // CBC encryption method, Pkcs7 padding method const encrypted = CryptoJS.AES.encrypt(srcs, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }) return encrypted.toString() } ``` ```python Python theme={null} import hashlib from Crypto.Cipher import AES import base64 # Generate signature def generate_msg_signature(client_id, timestamp, nonce, msg_encrypt): sorted_str = ''.join(sorted([client_id, timestamp, nonce, msg_encrypt])) hash_value = hashlib.sha1(sorted_str.encode('utf-8')).hexdigest() return hash_value # Decryption algorithm def generate_aes_decrypt(data_encrypt, client_id, client_secret): aes_key = client_secret.encode('utf-8') # Ensure the IV is 16 bytes long iv = client_id.encode('utf-8') iv = iv[:16] if len(iv) >= 16 else iv.ljust(16, b'\0') cipher = AES.new(aes_key, AES.MODE_CBC, iv) decrypted_data = cipher.decrypt(base64.b64decode(data_encrypt)) padding_len = decrypted_data[-1] return decrypted_data[:-padding_len].decode('utf-8') # Encryption algorithm def generate_aes_encrypt(data, client_id, client_secret): aes_key = client_secret.encode('utf-8') # Ensure the IV is 16 bytes long iv = client_id.encode('utf-8') iv = iv[:16] if len(iv) >= 16 else iv.ljust(16, b'\0') # Pkcs7 padding data_bytes = data.encode('utf-8') padding_len = AES.block_size - len(data_bytes) % AES.block_size padded_data = data_bytes + bytes([padding_len]) * padding_len cipher = AES.new(aes_key, AES.MODE_CBC, iv) encrypted_data = cipher.encrypt(padded_data) return base64.b64encode(encrypted_data).decode('utf-8') ``` ```java Java theme={null} import java.security.MessageDigest; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.util.Arrays; import java.nio.charset.StandardCharsets; import javax.xml.bind.DatatypeConverter; public class CryptoUtils { // Generate signature public static String generateMsgSignature(String clientId, String timestamp, String nonce, String msgEncrypt) { String[] arr = {clientId, timestamp, nonce, msgEncrypt}; Arrays.sort(arr); String sortedStr = String.join("", arr); return sha1(sortedStr); } // SHA-1 hash function private static String sha1(String input) { try { MessageDigest md = MessageDigest.getInstance("SHA-1"); byte[] hashBytes = md.digest(input.getBytes(StandardCharsets.UTF_8)); return DatatypeConverter.printHexBinary(hashBytes).toLowerCase(); } catch (Exception e) { e.printStackTrace(); return null; } } // Decryption algorithm public static String generateAesDecrypt(String dataEncrypt, String clientId, String clientSecret) { try { byte[] keyBytes = clientSecret.getBytes(StandardCharsets.UTF_8); byte[] ivBytes = clientId.getBytes(StandardCharsets.UTF_8); SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES"); IvParameterSpec ivSpec = new IvParameterSpec(ivBytes); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec); byte[] encryptedBytes = DatatypeConverter.parseHexBinary(dataEncrypt); byte[] decryptedBytes = cipher.doFinal(encryptedBytes); return new String(decryptedBytes, StandardCharsets.UTF_8); } catch (Exception e) { e.printStackTrace(); return null; } } // Encryption algorithm public static String generateAesEncrypt(String data, String clientId, String clientSecret) { try { byte[] keyBytes = clientSecret.getBytes(StandardCharsets.UTF_8); byte[] ivBytes = clientId.getBytes(StandardCharsets.UTF_8); SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES"); IvParameterSpec ivSpec = new IvParameterSpec(ivBytes); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec); byte[] encryptedBytes = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8)); return DatatypeConverter.printHexBinary(encryptedBytes).toLowerCase(); } catch (Exception e) { e.printStackTrace(); return null; } } // Example usage public static void main(String[] args) { String clientId = "your_client_id"; String clientSecret = "your_client_secret"; String timestamp = "your_timestamp"; String nonce = "your_nonce"; String msgEncrypt = "your_encrypted_message"; // Generate signature String signature = generateMsgSignature(clientId, timestamp, nonce, msgEncrypt); System.out.println("Signature: " + signature); // Encryption String data = "your_data_to_encrypt"; String encryptedData = generateAesEncrypt(data, clientId, clientSecret); System.out.println("Encrypted Data: " + encryptedData); // Decryption String decryptedData = generateAesDecrypt(encryptedData, clientId, clientSecret); System.out.println("Decrypted Data: " + decryptedData); } } ``` 2. Assume that our webhookUrl has obtained the corresponding data, such as the following corresponding data ```json theme={null} { "signature": "04e30dd43d9d8f95dd7c127dad617f0929d61c1d", "dataEncrypt": "LuG1OVSVIwOO/xpW00eSYo77Ncxa9h4VKmOJRjwoyoAmCIS/8FdJRJ+BpZn90BVAAg8xpU1bMmcDlAYDT010Wa9tNi1jivX25Ld03iA4EKs=", "timestamp": 1710757981609, "nonce": 1529 } ``` 3. To verify the correctness of the signature and decrypt the content, clientId and clientSecret are required. ```javascript Nodejs theme={null} // express example const obj = { "signature": "04e30dd43d9d8f95dd7c127dad617f0929d61c1d", "dataEncrypt": "LuG1OVSVIwOO/xpW00eSYo77Ncxa9h4VKmOJRjwoyoAmCIS/8FdJRJ+BpZn90BVAAg8xpU1bMmcDlAYDT010Wa9tNi1jivX25Ld03iA4EKs=", "timestamp": 1710757981609, "nonce": 1529 } let clientId = "AKDt8rWEczpYPzCGur2xE=" let clientSecret = "nmwUjMAK0PJpl0MOiXLOOOwZADm0gkLo" let signature = obj.signature let msg_encrypt = obj.dataEncrypt let timestamp = obj.timestamp let nonce = obj.nonce let newSignature = generateMsgSignature(clientId,timestamp,nonce,msg_encrypt) if (signature===newSignature) { let result = generateAesDecrypt(msg_encrypt,clientId,clientSecret) // Handle your own business logic response.status(200).json({}) // If the processing is successful,http statusCode:200 must be returned. }else { response.status(400).json({}) } ``` ```python Python theme={null} import hashlib from Crypto.Cipher import AES import base64 def generate_msg_signature(client_id, timestamp, nonce, msg_encrypt): sorted_str = ''.join(sorted([client_id, timestamp, nonce, msg_encrypt])) hash_value = hashlib.sha1(sorted_str.encode('utf-8')).hexdigest() return hash_value # Decryption algorithm def generate_aes_decrypt(data_encrypt, client_id, client_secret): aes_key = client_secret.encode('utf-8') # Ensure the IV is 16 bytes long iv = client_id.encode('utf-8') iv = iv[:16] if len(iv) >= 16 else iv.ljust(16, b'\0') cipher = AES.new(aes_key, AES.MODE_CBC, iv) decrypted_data = cipher.decrypt(base64.b64decode(data_encrypt)) padding_len = decrypted_data[-1] return decrypted_data[:-padding_len].decode('utf-8') # Example usage if __name__ == "__main__": obj = { "signature": "04e30dd43d9d8f95dd7c127dad617f0929d61c1d", "dataEncrypt": "LuG1OVSVIwOO/xpW00eSYo77Ncxa9h4VKmOJRjwoyoAmCIS/8FdJRJ+BpZn90BVAAg8xpU1bMmcDlAYDT010Wa9tNi1jivX25Ld03iA4EKs=", "timestamp": 1710757981609, "nonce": 1529 } clientId = "AKDt8rWEczpYPzCGur2xE=" clientSecret = "nmwUjMAK0PJpl0MOiXLOOOwZADm0gkLo" signature = obj["signature"] msg_encrypt = obj["dataEncrypt"] timestamp = obj["timestamp"] nonce = obj["nonce"] new_signature = generate_msg_signature(clientId, timestamp, nonce, msg_encrypt) if signature == new_signature: result = generate_aes_decrypt(msg_encrypt, clientId, clientSecret) # Handle your own business logic print("Decrypted Data:", result) # Return success http satusCode 200 else: # Return error http statuCode 400 ``` ```java Java theme={null} import java.security.MessageDigest; import java.util.Arrays; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.util.Base64; public class CryptoUtils { // Generate signature public static String generateMsgSignature(String clientId, long timestamp, int nonce, String msgEncrypt) { String[] arr = {clientId, String.valueOf(timestamp), String.valueOf(nonce), msgEncrypt}; Arrays.sort(arr); String sortedStr = String.join("", arr); return sha1(sortedStr); } // SHA-1 hash function private static String sha1(String input) { try { MessageDigest md = MessageDigest.getInstance("SHA-1"); byte[] hashBytes = md.digest(input.getBytes()); StringBuilder hexString = new StringBuilder(); for (byte b : hashBytes) { String hex = Integer.toHexString(0xff & b); if (hex.length() == 1) hexString.append('0'); hexString.append(hex); } return hexString.toString(); } catch (Exception e) { e.printStackTrace(); return null; } } // Decryption algorithm public static String generateAesDecrypt(String dataEncrypt, String clientId, String clientSecret) { try { byte[] keyBytes = clientSecret.getBytes(); byte[] ivBytes = clientId.getBytes(); SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES"); IvParameterSpec ivSpec = new IvParameterSpec(ivBytes); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec); byte[] encryptedBytes = Base64.getDecoder().decode(dataEncrypt); byte[] decryptedBytes = cipher.doFinal(encryptedBytes); return new String(decryptedBytes); } catch (Exception e) { e.printStackTrace(); return null; } } // Example usage public static void main(String[] args) { String clientId = "AKDt8rWEczpYPzCGur2xE="; String clientSecret = "nmwUjMAK0PJpl0MOiXLOOOwZADm0gkLo"; String signature = "04e30dd43d9d8f95dd7c127dad617f0929d61c1d"; String msgEncrypt = "LuG1OVSVIwOO/xpW00eSYo77Ncxa9h4VKmOJRjwoyoAmCIS/8FdJRJ+BpZn90BVAAg8xpU1bMmcDlAYDT010Wa9tNi1jivX25Ld03iA4EKs="; long timestamp = 1710757981609L; int nonce = 1529; String newSignature = generateMsgSignature(clientId, timestamp, nonce, msgEncrypt); if (signature.equals(newSignature)) { String result = generateAesDecrypt(msgEncrypt, clientId, clientSecret); // Handle your own business logic System.out.println("Decrypted Data: " + result); // must be Return success http satusCode 200 } else { // must be Return error http satusCode 400 } } } ``` # Usage Source: https://docs.akool.com/authentication/usage ### Overview OpenAPI supports two authentication methods. We **recommend using the direct API key method** for simplicity and better security. #### Method 1: Direct API Key (Recommended) The simplest way to authenticate is by using your API Key directly. Get your API Key from our API interfaces by clicking on the top API button on this page openAPI. **Note:** In the frontend interface, this is displayed as "API Key", but in code implementation, it's the same value as your previous clientSecret. 1. Login to our website 2. Click API icon 3. Click "API Credentials" to generate your API Key 4. Use the API Key directly in your requests All API requests should include your API Key in the HTTP header: **Custom x-api-key header** ``` x-api-key: {API Key} ``` #### Method 2: ClientId/API Key (clientSecret) - Legacy Method For backward compatibility, we also support the traditional clientId/clientSecret method: **Note:** Your API Key (displayed in frontend) is the same value as your previous clientSecret. In code, you can reference it as either clientSecret or use the x-api-key header format. 1. Login to our website 2. Click API icon 3. Click "API Credentials" to set your key pair (clientId, API Key) 4. Use the clientId/API Key to obtain an access token via the `/getToken` endpoint 5. Use the obtained token in subsequent API calls Bearer tokens are generally composed of a random string of characters. Formally, it takes the form of the "Bearer" keyword and the token value separated by spaces: ``` Authorization: Bearer {token} ``` Here is an example of an actual Bearer token: ``` Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjYyYTA2Mjg1N2YzNWNjNTJlM2UxNzYyMCIsInR5cGUiOiJ1c2VyIiwiZnJvbSI6InRvYiIsImVtYWlsIjoiZ3VvZG9uZ2RvbmdAYWtvb2wuY29tIiwiZmlyc3ROYW1lIjoiZGQiLCJ1aWQiOjkwMzI4LCJjb2RlIjoiNTY1NCIsImlhdCI6MTczMjg2NzczMiwiZXhwIjoxNzMyODY3NzMzfQ._pilTnv8sPsrKCzrAyh9Lsvyge8NPxUG5Y_8CTdxad0 ``` **Security Note:** Your API Key/token is secret! Do not share it with others or expose it in any client-side code (browser, application). Production requests must be routed through your own backend server, and your API Key can be securely loaded from environment variables or a key management service. ### API #### Using Direct API Key (Recommended) When using the direct API Key method, you can include your API Key in the HTTP headers using either format: **Custom x-api-key header** ``` x-api-key: {your-api-key} ``` No additional token generation step is required. Your API Key serves as the authentication token directly. #### Get Token (Legacy Method) ``` POST https://openapi.akool.com/api/open/v3/getToken ``` For users still using the clientId/API Key (clientSecret) method, use this endpoint to obtain an access token: **Body Attributes** | **Parameter** | **Description** | | ------------- | -------------------------------------------------------------------- | | clientId | Used for request creation authorization | | clientSecret | Used for request creation authorization (same value as your API Key) | **Response Attributes** | **Parameter** | **Value** | **Description** | | ------------- | --------- | ---------------------------------------------------- | | code | 1000 | Interface returns business status code(1000:success) | | token | | API token | Please note that the generated token is valid for more than 1 year. #### Example ##### Direct API Key Usage (Recommended) **Using x-api-key header** ```bash cURL theme={null} curl --location 'https://openapi.akool.com/api/your-endpoint' \ --header 'x-api-key: {{API Key}}' \ --header 'Content-Type: application/json' \ --data '{}' ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, ""); Request request = new Request.Builder() .url("https://openapi.akool.com/api/your-endpoint") .method("POST", body) .addHeader("x-api-key", "{{API Key}}") .addHeader("Content-Type", "application/json") .build(); Response response = client.newCall(request).execute(); ``` ```js Javascript theme={null} const myHeaders = new Headers(); myHeaders.append("x-api-key", "{{API Key}}"); myHeaders.append("Content-Type", "application/json"); const raw = JSON.stringify({}); const requestOptions = { method: "POST", headers: myHeaders, body: raw, redirect: "follow" }; fetch("https://openapi.akool.com/api/your-endpoint", requestOptions) .then((response) => response.text()) .then((result) => console.log(result)) .catch((error) => console.error(error)); ``` ```php PHP theme={null} '{{API Key}}', 'Content-Type' => 'application/json' ]; $body = '{}'; $request = new Request('POST', 'https://openapi.akool.com/api/your-endpoint', $headers, $body); $res = $client->sendAsync($request)->wait(); echo $res->getBody(); ?> ``` ```python Python theme={null} import requests import json url = "https://openapi.akool.com/api/your-endpoint" payload = json.dumps({}) headers = { 'x-api-key':'{{API Key}}', 'Content-Type': 'application/json' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text) ``` #### Legacy Token Generation Method **Body** ```json theme={null} { "clientId": "64db241f6d9e5c4bd136c187", "clientSecret": "openapi.akool.com" } ``` **Request** ```bash cURL theme={null} curl --location 'https://openapi.akool.com/api/open/v3/getToken' \ --header 'Content-Type: application/json' \ --data '{ "clientId": "64db241f6d9e5c4bd136c187", "clientSecret": "openapi.akool.com" }' ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient().newBuilder() .build(); MediaType mediaType = MediaType.parse("application/json"); RequestBody body = RequestBody.create(mediaType, "{\r\n \"clientId\": \"64db241f6d9e5c4bd136c187\",\r\n \"clientSecret\": \"openapi.akool.com\"\r\n}"); Request request = new Request.Builder() .url("https://openapi.akool.com/api/open/v3/getToken") .method("POST", body) .addHeader("Content-Type", "application/json") .build(); Response response = client.newCall(request).execute(); ``` ```js Javascript theme={null} const myHeaders = new Headers(); myHeaders.append("Content-Type", "application/json"); const raw = JSON.stringify({ "clientId": "64db241f6d9e5c4bd136c187", "clientSecret": "openapi.akool.com" }); const requestOptions = { method: "POST", headers: myHeaders, body: raw, redirect: "follow" }; fetch("https://openapi.akool.com/api/open/v3/getToken", requestOptions) .then((response) => response.text()) .then((result) => console.log(result)) .catch((error) => console.error(error)); ``` ```php PHP theme={null} 'application/json' ]; $body = '{ "clientId": "64db241f6d9e5c4bd136c187", "clientSecret": "openapi.akool.com" }'; $request = new Request('POST', 'https://openapi.akool.com/api/open/v3/getToken', $headers, $body); $res = $client->sendAsync($request)->wait(); echo $res->getBody(); ``` ```python Python theme={null} import requests import json url = "https://openapi.akool.com/api/open/v3/getToken" payload = json.dumps({ "clientId": "64db241f6d9e5c4bd136c187", "clientSecret": "openapi.akool.com" }) headers = { 'Content-Type': 'application/json' } response = requests.request("POST", url, headers=headers, data=payload) print(response.text) ``` **Response** ```json theme={null} { "code": 1000, "token": "xxxxxxxxxxxxxxxx" } ``` **Response Code Description** Please note that if the value of the response code is not equal to 1000, the request is failed or wrong | **Parameter** | **Value** | **Description** | | ------------- | --------- | ------------------------------------------------------ | | code | 1000 | Success | | code | 1101 | Invalid authorization or The request token has expired | | code | 1102 | Authorization cannot be empty | | code | 1200 | The account has been banned | # Change Logs Source: https://docs.akool.com/changelog API release notes and version history # Change Logs Track all API updates and new features. *** ## 2025 ### December 2025 * Added AI Model API endpoint ### November 2025 * Added Face Detection API endpoint ### October 2025 * Added batch multi-language translation support to Video Translation API ### September 2025 * Added Image Face Swap V4 API ### August 2025 * Added Image to Video API ### July 2025 * Added VoiceLab API ### June 2025 * Added Knowledge Base feature for Streaming Avatar ### April 2025 * Added Postman collection link ### March 2025 * Added Streaming Avatar JS SDK documentation ### February 2025 * Added Streaming Avatar API section ### January 2025 * Added JS SDK documentation *** ## 2024 ### December 2024 * Added Streaming Avatar V4 API and Talking Avatar API ### November 2024 * Added stream type support to Streaming Avatar API ### August 2024 * Added Jarvis Moderator API ### July 2024 * Added Error Code documentation ### June 2024 * Initial release *** ## How to Stay Updated Contact us to subscribe to API update notifications Read our blog for the latest news and tutorials # Streaming Avatar Integration Guide Source: https://docs.akool.com/implementation-guide/streaming-avatar Learn how to integrate streaming avatars using Agora, LiveKit, or TRTC SDK **🎉 New Feature Available!** Video interaction with streaming avatars is now live! You can now enable two-way video communication with your avatars, including camera switching capabilities and video quality controls. Check out the [Video Interaction](#video-interaction-with-the-avatar) section for implementation details. ## Overview The Streaming Avatar feature allows you to create interactive, real-time avatar experiences in your application. This guide provides a comprehensive walkthrough of integrating streaming avatars using **Agora SDK**, **LiveKit SDK**, or **TRTC SDK**, including: * Setting up real-time communication channels * Handling avatar interactions and responses * Managing audio streams * Implementing cleanup procedures * Optional LLM service integration Choose between three reliable WebRTC-based SDKs for low-latency streaming with our avatar service. The code examples in this guide use **synchronized tabs** - select your preferred provider (Agora, LiveKit, or TRTC) in any code block, and all code examples on the page will automatically switch to match your selection. ## Prerequisites ### 1. Install the SDK ```bash Agora theme={null} npm install agora-rtc-sdk-ng # or yarn add agora-rtc-sdk-ng ``` ```bash LiveKit theme={null} npm install livekit-client # or yarn add livekit-client ``` ```bash TRTC theme={null} npm install trtc-sdk-v5 # or yarn add trtc-sdk-v5 ``` ### 2. Import the required dependencies ```ts Agora theme={null} import AgoraRTC, { IAgoraRTCClient } from "agora-rtc-sdk-ng"; ``` ```ts LiveKit theme={null} import { Room, RoomEvent } from "livekit-client"; ``` ```ts TRTC theme={null} import TRTC from "trtc-sdk-v5"; ``` ### 3. Understanding Data Channel Limitations Agora SDK's `sendStreamMessage` is not exposed in the public API, so we need to add it manually to the type definitions: ```ts theme={null} interface RTCClient extends IAgoraRTCClient { sendStreamMessage(msg: Uint8Array | string, flag: boolean): Promise; } ``` **Important**: The Agora SDK has the following limitations ([reference](https://docs.agora.io/en/voice-calling/troubleshooting/error-codes?platform=android#data-stream-related-error-codes)): * Maximum message size: **1 KB (1,024 bytes)** * Maximum message frequency: **6 KB per second** LiveKit uses WebRTC data channels for message communication with more generous limits: **Important**: LiveKit data channel has the following limitations: * **Reliable mode**: Maximum message size of **15 KiB (15,360 bytes)** per message * **Lossy mode**: Recommended to keep messages under 1,300 bytes * For this integration, we use reliable mode which provides significantly larger message capacity than Agora For more details, refer to [LiveKit's Data Channel Documentation](https://docs.livekit.io/home/client/data/packets/). TRTC uses custom messages for communication with specific limitations: **Important**: TRTC data channel has the following limitations: * **Custom messages**: Maximum message size of **1 KB (1,024 bytes)** per message * **Rate limit**: 30 calls per second, 8 KB/s for custom messages * Messages are sent reliably and in order by default For more details, refer to [TRTC's Custom Message Documentation](https://web.sdk.qcloud.com/trtc/webrtc/v5/doc/en/TRTC.html#sendCustomMessage). ## Integration Flow The integration follows the same pattern regardless of which SDK you choose (Agora, LiveKit, or TRTC): ```mermaid theme={null} sequenceDiagram participant Client participant YourBackend participant Akool participant RTC Provider (Agora/LiveKit/TRTC) %% Session Creation - Two Paths alt Direct Browser Implementation Client->>Akool: Create session Akool-->>Client: Return RTC credentials else Backend Implementation Client->>YourBackend: Request session YourBackend->>Akool: Create session Akool-->>YourBackend: Return RTC credentials YourBackend-->>Client: Forward RTC credentials end %% RTC Connection Client->>RTC Provider (Agora/LiveKit/TRTC): Connect with credentials RTC Provider (Agora/LiveKit/TRTC)-->>Client: Connection established %% Optional LLM Integration alt Using Custom LLM service Client->>YourBackend: Send question to LLM YourBackend-->>Client: Return processed response end %% Message Flow Client->>RTC Provider (Agora/LiveKit/TRTC): Send message RTC Provider (Agora/LiveKit/TRTC)->>Akool: Forward message %% Response Flow Akool->>RTC Provider (Agora/LiveKit/TRTC): Stream avatar response RTC Provider (Agora/LiveKit/TRTC)->>Client: Forward streamed response %% Audio Flow (Optional) opt Audio Interaction Client->>RTC Provider (Agora/LiveKit/TRTC): Publish audio track RTC Provider (Agora/LiveKit/TRTC)->>Akool: Forward audio stream Akool->>RTC Provider (Agora/LiveKit/TRTC): Stream avatar response RTC Provider (Agora/LiveKit/TRTC)->>Client: Forward avatar response end %% Video Flow opt Video Interaction Client->>RTC Provider (Agora/LiveKit/TRTC): Publish video track RTC Provider (Agora/LiveKit/TRTC)->>Akool: Forward video stream Akool->>RTC Provider (Agora/LiveKit/TRTC): Stream avatar response RTC Provider (Agora/LiveKit/TRTC)->>Client: Forward avatar response end %% Cleanup - Two Paths alt Direct Browser Implementation Client->>RTC Provider (Agora/LiveKit/TRTC): Disconnect Client->>Akool: Close session else Backend Implementation Client->>RTC Provider (Agora/LiveKit/TRTC): Disconnect Client->>YourBackend: Request session closure YourBackend->>Akool: Close session end ``` ## Key Implementation Steps ### 1. Create a Live Avatar Session **Security Recommendation**: We strongly recommend implementing session management through your backend server rather than directly in the browser. This approach: * Protects your AKool API token from exposure * Allows for proper request validation and rate limiting * Enables usage tracking and monitoring * Provides better control over session lifecycle * Prevents unauthorized access to the API First, create a session to obtain Agora credentials. While both browser and backend implementations are possible, the backend approach is recommended for security: ```ts theme={null} // Recommended: Backend Implementation async function createSessionFromBackend(): Promise { // Your backend endpoint that securely wraps the AKool API const response = await fetch('https://your-backend.com/api/avatar/create-session', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ avatarId: "dvp_Tristan_cloth2_1080P", duration: 600, }) }); if (!response.ok) { throw new Error('Failed to create session through backend'); } return response.json(); } // Not Recommended: Direct Browser Implementation // Only use this for development/testing purposes async function createSessionInBrowser(): Promise { const response = await fetch('https://openapi.akool.com/api/open/v4/liveAvatar/session/create', { method: 'POST', headers: { 'x-api-key':'{{API Key}}', // Security risk: Token exposed in browser 'Content-Type': 'application/json' }, body: JSON.stringify({ avatar_id: "dvp_Tristan_cloth2_1080P", duration: 600, }) }); if (!response.ok) { throw new Error(`Failed to create session: ${response.status} ${response.statusText}`); } const res = await response.json(); return res.data; } ``` ### 2. Initialize the Client/Room Create and configure the client or room: ```ts Agora theme={null} async function initializeAgoraClient(credentials) { const client = AgoraRTC.createClient({ mode: 'rtc', codec: 'vp8' }); try { await client.join( credentials.agora_app_id, credentials.agora_channel, credentials.agora_token, credentials.agora_uid ); return client; } catch (error) { console.error('Error joining channel:', error); throw error; } } ``` ```ts LiveKit theme={null} import { Room } from 'livekit-client'; async function initializeLiveKitRoom(credentials) { const room = new Room({ adaptiveStream: true, dynacast: true, }); try { await room.connect( credentials.livekit_url, credentials.livekit_token, { autoSubscribe: true, } ); return room; } catch (error) { console.error('Error connecting to room:', error); throw error; } } ``` ```ts TRTC theme={null} async function initializeTRTCClient(credentials) { const client = TRTC.create(); try { await client.enterRoom({ sdkAppId: credentials.trtc_app_id, roomId: credentials.trtc_room_id, userId: credentials.trtc_user_id, userSig: credentials.trtc_user_sig, }); return client; } catch (error) { console.error('Error entering room:', error); throw error; } } ``` ### 3. Subscribe to Audio and Video Stream Subscribe to the audio and video stream of the avatar: ```ts Agora theme={null} async function subscribeToAvatarStream(client: IAgoraRTCClient) { const onUserPublish = async (user: IAgoraRTCRemoteUser, mediaType: 'video' | 'audio') => { const remoteTrack = await client.subscribe(user, mediaType); remoteTrack.play(); }; const onUserUnpublish = async (user: IAgoraRTCRemoteUser, mediaType: 'video' | 'audio') => { await client.unsubscribe(user, mediaType); }; client.on('user-published', onUserPublish); client.on('user-unpublished', onUserUnpublish); } ``` ```ts LiveKit theme={null} import { RoomEvent, RemoteVideoTrack, RemoteAudioTrack } from 'livekit-client'; async function subscribeToAvatarStream(room: Room) { room.on(RoomEvent.TrackSubscribed, (track, publication, participant) => { if (track.kind === 'video' && track instanceof RemoteVideoTrack) { const videoElement = document.getElementById('remote-video') as HTMLVideoElement; if (videoElement) { track.attach(videoElement); videoElement.play(); } } else if (track.kind === 'audio' && track instanceof RemoteAudioTrack) { const audioElement = document.createElement('audio'); audioElement.autoplay = true; audioElement.volume = 1.0; document.body.appendChild(audioElement); track.attach(audioElement); } }); room.on(RoomEvent.TrackUnsubscribed, (track, publication, participant) => { track.detach(); }); } ``` ```ts TRTC theme={null} async function subscribeToAvatarStream(client: TRTC) { // Handle remote user video stream client.on(TRTC.EVENT.REMOTE_VIDEO_AVAILABLE, (event) => { const { userId, streamType } = event; const videoElement = document.getElementById('remote-video') as HTMLVideoElement; if (videoElement) { client.startRemoteView({ userId, streamType: streamType || TRTC.TRTCVideoStreamTypeBig, view: videoElement }); } }); // Handle remote user audio stream client.on(TRTC.EVENT.REMOTE_AUDIO_AVAILABLE, (event) => { const { userId } = event; client.startRemoteAudio({ userId, volume: 100 }); }); // Handle stream removal client.on(TRTC.EVENT.REMOTE_VIDEO_UNAVAILABLE, (event) => { const { userId } = event; client.stopRemoteView({ userId }); }); client.on(TRTC.EVENT.REMOTE_AUDIO_UNAVAILABLE, (event) => { const { userId } = event; client.stopRemoteAudio({ userId }); }); } ``` ### 4. Set Up Message Handling Configure message listeners to handle avatar responses: ```ts Agora theme={null} function setupMessageHandlers(client: IAgoraRTCClient) { let answer = ''; client.on('stream-message', (uid, message) => { try { const parsedMessage = JSON.parse(message); if (parsedMessage.type === 'chat') { const payload = parsedMessage.pld; if (payload.from === 'bot') { if (!payload.fin) { answer += payload.text; } else { console.log('Avatar response:', answer); answer = ''; } } else if (payload.from === 'user') { console.log('User message:', payload.text); } } else if (parsedMessage.type === 'command') { if (parsedMessage.pld.code !== 1000) { console.error('Command failed:', parsedMessage.pld.msg); } } } catch (error) { console.error('Error parsing message:', error); } }); } ``` ```ts LiveKit theme={null} import { RoomEvent } from 'livekit-client'; function setupMessageHandlers(room: Room) { let answer = ''; room.on(RoomEvent.DataReceived, (payload: Uint8Array, participant) => { try { const message = new TextDecoder().decode(payload); const parsedMessage = JSON.parse(message); if (parsedMessage.type === 'chat') { const payload = parsedMessage.pld; if (payload.from === 'bot') { if (!payload.fin) { answer += payload.text; } else { console.log('Avatar response:', answer); answer = ''; } } else if (payload.from === 'user') { console.log('User message:', payload.text); } } else if (parsedMessage.type === 'command') { if (parsedMessage.pld.code !== 1000) { console.error('Command failed:', parsedMessage.pld.msg); } } } catch (error) { console.error('Error parsing message:', error); } }); } ``` ```ts TRTC theme={null} function setupMessageHandlers(client: TRTC) { let answer = ''; client.on(TRTC.EVENT.CUSTOM_MESSAGE, (event) => { try { const { data } = event; const message = new TextDecoder().decode(new Uint8Array(data)); const parsedMessage = JSON.parse(message); if (parsedMessage.type === 'chat') { const payload = parsedMessage.pld; if (payload.from === 'bot') { if (!payload.fin) { answer += payload.text; } else { console.log('Avatar response:', answer); answer = ''; } } else if (payload.from === 'user') { console.log('User message:', payload.text); } } else if (parsedMessage.type === 'command') { if (parsedMessage.pld.code !== 1000) { console.error('Command failed:', parsedMessage.pld.msg); } } } catch (error) { console.error('Error parsing message:', error); } }); } ``` ### 5. Send Messages to Avatar Implement functions to interact with the avatar: ```ts Agora theme={null} async function sendMessageToAvatar(client: IAgoraRTCClient, question: string) { const message = { v: 2, type: "chat", mid: `msg-${Date.now()}`, idx: 0, fin: true, pld: { text: question, } }; try { await client.sendStreamMessage(JSON.stringify(message), false); } catch (error) { console.error('Error sending message:', error); throw error; } } ``` ```ts LiveKit theme={null} async function sendMessageToAvatar(room: Room, question: string) { const message = { v: 2, type: "chat", mid: `msg-${Date.now()}`, idx: 0, fin: true, pld: { text: question, } }; try { const encoder = new TextEncoder(); const data = encoder.encode(JSON.stringify(message)); await room.localParticipant.publishData(data, { reliable: true }); } catch (error) { console.error('Error sending message:', error); throw error; } } ``` ```ts TRTC theme={null} async function sendMessageToAvatar(client: TRTC, question: string) { const message = { v: 2, type: "chat", mid: `msg-${Date.now()}`, idx: 0, fin: true, pld: { text: question, } }; try { const encoder = new TextEncoder(); const data = encoder.encode(JSON.stringify(message)); await client.sendCustomMessage({ cmdId: 1, data: data }); } catch (error) { console.error('Error sending message:', error); throw error; } } ``` In real-world scenarios with Agora, the message size is limited to 1KB and the message frequency is limited to 6KB per second, so we need to split large messages into chunks and send them separately: ```ts theme={null} export async function sendMessageToAvatar(client: RTCClient, messageId: string, content: string) { const MAX_ENCODED_SIZE = 950; const BYTES_PER_SECOND = 6000; // Improved message encoder with proper typing const encodeMessage = (text: string, idx: number, fin: boolean): Uint8Array => { const message: StreamMessage = { v: 2, type: 'chat', mid: messageId, idx, fin, pld: { text, }, }; return new TextEncoder().encode(JSON.stringify(message)); }; // Validate inputs if (!content) { throw new Error('Content cannot be empty'); } // Calculate maximum content length const baseEncoded = encodeMessage('', 0, false); const maxQuestionLength = Math.floor((MAX_ENCODED_SIZE - baseEncoded.length) / 4); // Split message into chunks const chunks: string[] = []; let remainingMessage = content; let chunkIndex = 0; while (remainingMessage.length > 0) { let chunk = remainingMessage.slice(0, maxQuestionLength); let encoded = encodeMessage(chunk, chunkIndex, false); // Binary search for optimal chunk size if needed while (encoded.length > MAX_ENCODED_SIZE && chunk.length > 1) { chunk = chunk.slice(0, Math.ceil(chunk.length / 2)); encoded = encodeMessage(chunk, chunkIndex, false); } if (encoded.length > MAX_ENCODED_SIZE) { throw new Error('Message encoding failed: content too large for chunking'); } chunks.push(chunk); remainingMessage = remainingMessage.slice(chunk.length); chunkIndex++; } log(`Splitting message into ${chunks.length} chunks`); // Send chunks with rate limiting for (let i = 0; i < chunks.length; i++) { const isLastChunk = i === chunks.length - 1; const encodedChunk = encodeMessage(chunks[i], i, isLastChunk); const chunkSize = encodedChunk.length; const minimumTimeMs = Math.ceil((1000 * chunkSize) / BYTES_PER_SECOND); const startTime = Date.now(); log(`Sending chunk ${i + 1}/${chunks.length}, size=${chunkSize} bytes`); try { await client.sendStreamMessage(encodedChunk, false); } catch (error: unknown) { throw new Error(`Failed to send chunk ${i + 1}: ${error instanceof Error ? error.message : 'Unknown error'}`); } if (!isLastChunk) { const elapsedMs = Date.now() - startTime; const remainingDelay = Math.max(0, minimumTimeMs - elapsedMs); if (remainingDelay > 0) { await new Promise((resolve) => setTimeout(resolve, remainingDelay)); } } } } ``` **LiveKit Note**: Unlike Agora's 1KB limit, LiveKit supports messages up to 15 KiB in reliable mode, so chunking is generally not needed for typical conversational messages. For very large messages (over 15 KiB), you would need to implement similar chunking logic. **TRTC Note**: TRTC has the same 1KB message size limit as Agora, so you would need to implement similar chunking logic for large messages. The chunking approach shown above for Agora can be adapted for TRTC by replacing `client.sendStreamMessage()` with `client.sendCustomMessage()`. ### 6. Control Avatar Parameters Implement functions to control avatar settings: ```ts Agora theme={null} async function setAvatarParams(client: IAgoraRTCClient, params: { vid?: string; lang?: string; mode?: number; bgurl?: string; }) { const message = { v: 2, type: 'command', mid: `msg-${Date.now()}`, pld: { cmd: 'set-params', data: params } }; await client.sendStreamMessage(JSON.stringify(message), false); } async function interruptAvatar(client: IAgoraRTCClient) { const message = { v: 2, type: 'command', mid: `msg-${Date.now()}`, pld: { cmd: 'interrupt' } }; await client.sendStreamMessage(JSON.stringify(message), false); } ``` ```ts LiveKit theme={null} async function setAvatarParams(room: Room, params: { vid?: string; lang?: string; mode?: number; bgurl?: string; }) { const message = { v: 2, type: 'command', mid: `msg-${Date.now()}`, pld: { cmd: 'set-params', data: params } }; const encoder = new TextEncoder(); const data = encoder.encode(JSON.stringify(message)); await room.localParticipant.publishData(data, { reliable: true }); } async function interruptAvatar(room: Room) { const message = { v: 2, type: 'command', mid: `msg-${Date.now()}`, pld: { cmd: 'interrupt' } }; const encoder = new TextEncoder(); const data = encoder.encode(JSON.stringify(message)); await room.localParticipant.publishData(data, { reliable: true }); } ``` ```ts TRTC theme={null} async function setAvatarParams(client: TRTC, params: { vid?: string; lang?: string; mode?: number; bgurl?: string; }) { const message = { v: 2, type: 'command', mid: `msg-${Date.now()}`, pld: { cmd: 'set-params', data: params } }; const encoder = new TextEncoder(); const data = encoder.encode(JSON.stringify(message)); await client.sendCustomMessage({ cmdId: 1, data: data.buffer }); } async function interruptAvatar(client: TRTC) { const message = { v: 2, type: 'command', mid: `msg-${Date.now()}`, pld: { cmd: 'interrupt' } }; const encoder = new TextEncoder(); const data = encoder.encode(JSON.stringify(message)); await client.sendCustomMessage({ cmdId: 1, data: data.buffer }); } ``` ### 7. Audio Interaction With The Avatar To enable audio interaction with the avatar, you'll need to publish your local audio stream: ```ts Agora theme={null} async function publishAudio(client: IAgoraRTCClient) { // Create a microphone audio track const audioTrack = await AgoraRTC.createMicrophoneAudioTrack(); try { // Publish the audio track to the channel await client.publish(audioTrack); console.log("Audio publishing successful"); return audioTrack; } catch (error) { console.error("Error publishing audio:", error); throw error; } } // Example usage with audio controls async function setupAudioInteraction(client: IAgoraRTCClient) { let audioTrack; // Start audio async function startAudio() { try { audioTrack = await publishAudio(client); } catch (error) { console.error("Failed to start audio:", error); } } // Stop audio async function stopAudio() { if (audioTrack) { // Stop and close the audio track audioTrack.stop(); audioTrack.close(); await client.unpublish(audioTrack); audioTrack = null; } } // Mute/unmute audio function toggleAudio(muted: boolean) { if (audioTrack) { if (muted) { audioTrack.setEnabled(false); } else { audioTrack.setEnabled(true); } } } return { startAudio, stopAudio, toggleAudio }; } ``` ```ts LiveKit theme={null} import { createLocalAudioTrack } from 'livekit-client'; async function publishAudio(room: Room) { // Create a microphone audio track const audioTrack = await createLocalAudioTrack(); try { // Publish the audio track to the room await room.localParticipant.publishTrack(audioTrack); console.log("Audio publishing successful"); return audioTrack; } catch (error) { console.error("Error publishing audio:", error); throw error; } } // Example usage with audio controls async function setupAudioInteraction(room: Room) { let audioTrack; // Start audio async function startAudio() { try { audioTrack = await publishAudio(room); } catch (error) { console.error("Failed to start audio:", error); } } // Stop audio async function stopAudio() { if (audioTrack) { // Stop and unpublish the audio track audioTrack.stop(); await room.localParticipant.unpublishTrack(audioTrack); audioTrack = null; } } // Mute/unmute audio function toggleAudio(muted: boolean) { if (audioTrack) { audioTrack.setMuted(muted); } } return { startAudio, stopAudio, toggleAudio }; } ``` ```ts TRTC theme={null} async function publishAudio(client: TRTC) { try { // Start local audio capture await client.startLocalAudio({ quality: TRTC.TRTCAudioQualityDefault }); console.log("Audio publishing successful"); return true; } catch (error) { console.error("Error publishing audio:", error); throw error; } } // Example usage with audio controls async function setupAudioInteraction(client: TRTC) { let isAudioEnabled = false; // Start audio async function startAudio() { try { await publishAudio(client); isAudioEnabled = true; } catch (error) { console.error("Failed to start audio:", error); } } // Stop audio async function stopAudio() { if (isAudioEnabled) { try { await client.stopLocalAudio(); isAudioEnabled = false; } catch (error) { console.error("Failed to stop audio:", error); } } } // Mute/unmute audio function toggleAudio(muted: boolean) { if (isAudioEnabled) { client.muteLocalAudio(muted); } } return { startAudio, stopAudio, toggleAudio }; } ``` Now you can integrate audio controls into your application: ```ts Agora theme={null} async function initializeWithAudio() { try { // Initialize avatar const client = await initializeStreamingAvatar(); // Setup audio controls const audioControls = await setupAudioInteraction(client); // Start audio when needed await audioControls.startAudio(); // Example of muting/unmuting audioControls.toggleAudio(true); // mute audioControls.toggleAudio(false); // unmute // Stop audio when done await audioControls.stopAudio(); } catch (error) { console.error("Error initializing with audio:", error); } } ``` ```ts LiveKit theme={null} async function initializeWithAudio() { try { // Initialize avatar const room = await initializeStreamingAvatar(); // Setup audio controls const audioControls = await setupAudioInteraction(room); // Start audio when needed await audioControls.startAudio(); // Example of muting/unmuting audioControls.toggleAudio(true); // mute audioControls.toggleAudio(false); // unmute // Stop audio when done await audioControls.stopAudio(); } catch (error) { console.error("Error initializing with audio:", error); } } ``` ```ts TRTC theme={null} async function initializeWithAudio() { try { // Initialize avatar const client = await initializeStreamingAvatar(); // Setup audio controls const audioControls = await setupAudioInteraction(client); // Start audio when needed await audioControls.startAudio(); // Example of muting/unmuting audioControls.toggleAudio(true); // mute audioControls.toggleAudio(false); // unmute // Stop audio when done await audioControls.stopAudio(); } catch (error) { console.error("Error initializing with audio:", error); } } ``` **Additional Resources:** * [Agora Web SDK Documentation](https://docs.agora.io/en/voice-calling/get-started/get-started-sdk?platform=web#publish-a-local-audio-track) * [LiveKit Web SDK Documentation](https://docs.livekit.io/client-sdk-js/) ### 8. Integrating your own LLM service (optional) You can integrate your own LLM service to process messages before sending them to the avatar. Here's how to do it: ```ts theme={null} // Define the LLM service response interface interface LLMResponse { answer: string; } // Set the avatar to retelling mode await setAvatarParams(client, { mode: 1, }); // Create a wrapper for your LLM service async function processWithLLM(question: string): Promise { try { const response = await fetch('YOUR_LLM_SERVICE_ENDPOINT', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ question, }) }); if (!response.ok) { throw new Error('LLM service request failed'); } return await response.json(); } catch (error) { console.error('Error processing with LLM:', error); throw error; } } ``` ```ts Agora theme={null} async function sendMessageToAvatarWithLLM( client: IAgoraRTCClient, question: string ) { try { // Process the question with your LLM service const llmResponse = await processWithLLM(question); // Prepare the message with LLM response const message = { v: 2, type: "chat", mid: `msg-${Date.now()}`, idx: 0, fin: true, pld: { text: llmResponse.answer // Use the LLM-processed response } }; // Send the processed message to the avatar await client.sendStreamMessage(JSON.stringify(message), false); } catch (error) { console.error('Error in LLM-enhanced message sending:', error); throw error; } } ``` ```ts LiveKit theme={null} async function sendMessageToAvatarWithLLM( room: Room, question: string ) { try { // Process the question with your LLM service const llmResponse = await processWithLLM(question); // Prepare the message with LLM response const message = { v: 2, type: "chat", mid: `msg-${Date.now()}`, idx: 0, fin: true, pld: { text: llmResponse.answer // Use the LLM-processed response } }; // Send the processed message to the avatar const encoder = new TextEncoder(); const data = encoder.encode(JSON.stringify(message)); await room.localParticipant.publishData(data, { reliable: true }); } catch (error) { console.error('Error in LLM-enhanced message sending:', error); throw error; } } ``` ```ts TRTC theme={null} async function sendMessageToAvatarWithLLM( client: TRTC, question: string ) { try { // Process the question with your LLM service const llmResponse = await processWithLLM(question); // Prepare the message with LLM response const message = { v: 2, type: "chat", mid: `msg-${Date.now()}`, idx: 0, fin: true, pld: { text: llmResponse.answer // Use the LLM-processed response } }; // Send the processed message to the avatar const encoder = new TextEncoder(); const data = encoder.encode(JSON.stringify(message)); await client.sendCustomMessage({ cmdId: 1, data: data }); } catch (error) { console.error('Error in LLM-enhanced message sending:', error); throw error; } } ``` *Remember to*: 1. Implement proper rate limiting for your LLM service 2. Handle token limits appropriately 3. Implement retry logic for failed LLM requests 4. Consider implementing streaming responses if your LLM service supports it 5. Cache common responses when appropriate ### 9. Cleanup Cleanup can also be performed either directly or through your backend: ```ts Agora theme={null} // Browser Implementation async function cleanupInBrowser(client: IAgoraRTCClient, sessionId: string) { await fetch('https://openapi.akool.com/api/open/v4/liveAvatar/session/close', { method: 'POST', headers: { 'x-api-key':'{{API Key}}' }, body: JSON.stringify({ id: sessionId }) }); await performClientCleanup(client); } // Backend Implementation async function cleanupFromBackend(client: IAgoraRTCClient, sessionId: string) { await fetch('https://your-backend.com/api/avatar/close-session', { method: 'POST', body: JSON.stringify({ sessionId }) }); await performClientCleanup(client); } // Shared cleanup logic async function performClientCleanup(client: IAgoraRTCClient) { // Remove event listeners client.removeAllListeners('user-published'); client.removeAllListeners('user-unpublished'); client.removeAllListeners('stream-message'); // Stop audio/video and unpublish if they're still running if (audioControls) { await audioControls.stopAudio(); } if (videoControls) { await videoControls.stopVideo(); } // Leave the Agora channel await client.leave(); } ``` ```ts LiveKit theme={null} // Browser Implementation async function cleanupInBrowser(room: Room, sessionId: string) { await fetch('https://openapi.akool.com/api/open/v4/liveAvatar/session/close', { method: 'POST', headers: { 'x-api-key':'{{API Key}}' }, body: JSON.stringify({ id: sessionId }) }); await performClientCleanup(room); } // Backend Implementation async function cleanupFromBackend(room: Room, sessionId: string) { await fetch('https://your-backend.com/api/avatar/close-session', { method: 'POST', body: JSON.stringify({ sessionId }) }); await performClientCleanup(room); } // Shared cleanup logic async function performClientCleanup(room: Room) { // Remove event listeners room.removeAllListeners(); // Stop and unpublish all local tracks room.localParticipant.audioTracks.forEach((publication) => { const track = publication.track; if (track) { track.stop(); room.localParticipant.unpublishTrack(track); } }); room.localParticipant.videoTracks.forEach((publication) => { const track = publication.track; if (track) { track.stop(); room.localParticipant.unpublishTrack(track); } }); // Disconnect from the LiveKit room await room.disconnect(); } ``` ```ts TRTC theme={null} // Browser Implementation async function cleanupInBrowser(client: TRTC, sessionId: string) { await fetch('https://openapi.akool.com/api/open/v4/liveAvatar/session/close', { method: 'POST', headers: { 'x-api-key':'{{API Key}}' }, body: JSON.stringify({ id: sessionId }) }); await performClientCleanup(client); } // Backend Implementation async function cleanupFromBackend(client: TRTC, sessionId: string) { await fetch('https://your-backend.com/api/avatar/close-session', { method: 'POST', body: JSON.stringify({ sessionId }) }); await performClientCleanup(client); } // Shared cleanup logic async function performClientCleanup(client: TRTC) { // Remove event listeners client.removeAllListeners(); // Stop local audio and video try { await client.stopLocalAudio(); } catch (error) { console.warn('Error stopping local audio:', error); } try { await client.stopLocalVideo(); } catch (error) { console.warn('Error stopping local video:', error); } // Exit the room await client.exitRoom(); } ``` When implementing through your backend, make sure to: * Securely store your AKool API token * Implement proper authentication and rate limiting * Handle errors appropriately * Consider implementing session management and monitoring ### 10. Putting It All Together Here's how to use all the components together: ```ts Agora theme={null} async function initializeStreamingAvatar() { let client; let session; try { // Create session and get credentials session = await createSession(); const { credentials } = session; // Initialize Agora client client = await initializeAgoraClient(credentials); // Subscribe to the audio and video stream of the avatar await subscribeToAvatarStream(client); // Set up message handlers setupMessageHandlers(client); // Example usage await sendMessageToAvatar(client, "Hello!"); // Or use your own LLM service await sendMessageToAvatarWithLLM(client, "Hello!"); // Example of voice interaction await interruptAvatar(client); // Example of Audio Interaction With The Avatar await setupAudioInteraction(client); // Example of changing avatar parameters await setAvatarParams(client, { lang: "en", vid: "new_voice_id" }); return client; } catch (error) { console.error('Error initializing streaming avatar:', error); if (client && session) { await cleanup(client, session._id); } throw error; } } ``` ```ts LiveKit theme={null} async function initializeStreamingAvatar() { let room; let session; try { // Create session and get credentials session = await createSession(); const { credentials } = session; // Initialize LiveKit room room = await initializeLiveKitRoom(credentials); // Subscribe to the audio and video stream of the avatar await subscribeToAvatarStream(room); // Set up message handlers setupMessageHandlers(room); // Example usage await sendMessageToAvatar(room, "Hello!"); // Or use your own LLM service await sendMessageToAvatarWithLLM(room, "Hello!"); // Example of voice interaction await interruptAvatar(room); // Example of Audio Interaction With The Avatar await setupAudioInteraction(room); // Example of changing avatar parameters await setAvatarParams(room, { lang: "en", vid: "new_voice_id" }); return room; } catch (error) { console.error('Error initializing streaming avatar:', error); if (room && session) { await cleanup(room, session._id); } throw error; } } ``` ```ts TRTC theme={null} async function initializeStreamingAvatar() { let client; let session; try { // Create session and get credentials session = await createSession(); const { credentials } = session; // Initialize TRTC client client = await initializeTRTCClient(credentials); // Subscribe to the audio and video stream of the avatar await subscribeToAvatarStream(client); // Set up message handlers setupMessageHandlers(client); // Example usage await sendMessageToAvatar(client, "Hello!"); // Or use your own LLM service await sendMessageToAvatarWithLLM(client, "Hello!"); // Example of voice interaction await interruptAvatar(client); // Example of Audio Interaction With The Avatar await setupAudioInteraction(client); // Example of changing avatar parameters await setAvatarParams(client, { lang: "en", vid: "new_voice_id" }); return client; } catch (error) { console.error('Error initializing streaming avatar:', error); if (client && session) { await cleanup(client, session._id); } throw error; } } ``` ## Additional Resources ### Agora SDK Resources * [Agora Web SDK Documentation](https://docs.agora.io/en/sdks?platform=web) * [Agora Web SDK API Reference](https://api-ref.agora.io/en/video-sdk/web/4.x/index.html) * [Agora Data Stream Error Codes](https://docs.agora.io/en/voice-calling/troubleshooting/error-codes?platform=android#data-stream-related-error-codes) ### LiveKit SDK Resources * [LiveKit Web SDK Documentation](https://docs.livekit.io/client-sdk-js/) * [LiveKit Web SDK API Reference](https://docs.livekit.io/client-sdk-js/classes/Room.html) * [LiveKit Data Channel Documentation](https://docs.livekit.io/home/client/data/packets/) ### TRTC SDK Resources * [TRTC Web SDK Documentation](https://web.sdk.qcloud.com/trtc/webrtc/v5/doc/en/index.html) * [TRTC Web SDK API Reference](https://web.sdk.qcloud.com/trtc/webrtc/v5/doc/en/TRTC.html) * [TRTC Custom Message Documentation](https://web.sdk.qcloud.com/trtc/webrtc/v5/doc/en/TRTC.html#sendCustomMessage) ### AKool API Resources * [AKool OpenAPI Error Codes](/ai-tools-suite/live-avatar#response-code-description) # Akool AI Tools Suite Documentation Source: https://docs.akool.com/index Comprehensive documentation for Akool AI tools including face swap, voice lab, video translation, and more. # Welcome to Akool AI Tools Suite Welcome to the comprehensive documentation for Akool's AI Tools Suite. This documentation provides detailed information about our cutting-edge AI technologies and how to integrate them into your applications. ## What's Available Our AI Tools Suite includes: * **Face Swap & Live Face Swap** - Advanced face swapping technology * **Voice Lab** - AI-powered voice synthesis and manipulation * **Video Translation** - Multi-language video translation with AI * **Talking Photo & Avatar** - Bring photos and avatars to life * **Background Change** - AI-powered background replacement * **Lip Sync** - Synchronize lip movements with audio * **Image Generation** - Create stunning images with AI * **And much more...** ## Quick Start 1. **Authentication** - Learn how to authenticate with our API 2. **Implementation Guide** - Follow our step-by-step implementation guides 3. **SDK Documentation** - Integrate with our JavaScript SDK 4. **API Reference** - Detailed API documentation for all endpoints ## Getting Help * **Support**: Contact us at [info@akool.com](mailto:info@akool.com) * **GitHub**: Visit our [GitHub repository](https://github.com/AKOOL-Official) * **Postman**: Try our [Postman collection](https://www.postman.com/akoolai/team-workspace/collection/40971792-f9172546-2d7e-4b28-bb20-b86988f3ab1d?action=share\&creator=40971792) * **Blog**: Read our latest updates on [akool.com/blog](https://akool.com/blog) Start exploring our documentation to discover how Akool AI can transform your applications! # Streaming Avatar SDK API Reference Source: https://docs.akool.com/sdk/jssdk-api Complete API documentation for akool-streaming-avatar-sdk ## Overview This document provides comprehensive API documentation for the [akool-streaming-avatar-sdk](https://www.npmjs.com/package/akool-streaming-avatar-sdk) package. The SDK provides a generic JavaScript interface for integrating Agora RTC streaming avatar functionality into any JavaScript application. **Package Links:** * [NPM Package](https://www.npmjs.com/package/akool-streaming-avatar-sdk) * [GitHub Repository](https://github.com/akool-rinku/akool-streaming-avatar-sdk) * **Current Version:** 1.0.6 *** # **GenericAgoraSDK Class Documentation** ## **Constructor** ### **`new GenericAgoraSDK(options?: { mode?: string; codec?: SDK_CODEC })`** Creates an instance of the Generic Agora SDK. #### **Parameters:** * `options.mode` (string) - Optional. SDK mode (default: "rtc") * `options.codec` (SDK\_CODEC) - Optional. Video codec (e.g., "vp8", "h264") #### **Example Usage:** ```javascript theme={null} import { GenericAgoraSDK } from 'akool-streaming-avatar-sdk'; const agoraSDK = new GenericAgoraSDK({ mode: "rtc", codec: "vp8" }); ``` *** ## **Connection Management** ### **`async joinChannel(credentials: AgoraCredentials): Promise`** Joins an Agora RTC channel using the provided credentials. #### **Parameters:** * `credentials` (AgoraCredentials) - Agora connection credentials #### **Example Usage:** ```javascript theme={null} await agoraSDK.joinChannel({ agora_app_id: "your-agora-app-id", agora_channel: "your-channel-name", agora_token: "your-agora-token", agora_uid: 12345 }); ``` ### **`async leaveChannel(): Promise`** Leaves the current Agora RTC channel. #### **Example Usage:** ```javascript theme={null} await agoraSDK.leaveChannel(); ``` ### **`async closeStreaming(cb?: () => void): Promise`** Closes all connections and performs cleanup. #### **Parameters:** * `cb` (function) - Optional callback function to execute after closing #### **Example Usage:** ```javascript theme={null} await agoraSDK.closeStreaming(() => { console.log("Streaming closed successfully"); }); ``` ### **`isConnected(): boolean`** Checks if the SDK is connected to Agora services. #### **Returns:** * `boolean` - Connection status #### **Example Usage:** ```javascript theme={null} const connected = agoraSDK.isConnected(); console.log("Connected:", connected); ``` ### **`isChannelJoined(): boolean`** Checks if the SDK has joined a channel. #### **Returns:** * `boolean` - Channel join status #### **Example Usage:** ```javascript theme={null} const joined = agoraSDK.isChannelJoined(); console.log("Channel joined:", joined); ``` *** ## **Chat Management** ### **`async joinChat(metadata: Metadata): Promise`** Initializes the avatar chat session with the specified parameters. #### **Parameters:** * `metadata` (Metadata) - Avatar configuration parameters #### **Example Usage:** ```javascript theme={null} await agoraSDK.joinChat({ vid: "voice-id-12345", lang: "en", mode: 2, // 1 for repeat mode, 2 for dialog mode bgurl: "https://example.com/background.jpg" }); ``` ### **`setParameters(metadata: Metadata): void`** Sets avatar parameters. Refer to the avatar parameter documentation for details. #### **Parameters:** * `metadata` (Metadata) - Avatar configuration parameters #### **Example Usage:** ```javascript theme={null} agoraSDK.setParameters({ vid: "new-voice-id", lang: "es", mode: 1 }); ``` ### **`async leaveChat(): Promise`** Leaves the chat session but maintains the channel connection. #### **Example Usage:** ```javascript theme={null} await agoraSDK.leaveChat(); ``` ### **`async sendMessage(content: string): Promise`** Sends a text message to the avatar. #### **Parameters:** * `content` (string) - The message content to send #### **Example Usage:** ```javascript theme={null} await agoraSDK.sendMessage("Hello, how are you today?"); ``` ### **`async interrupt(): Promise`** Interrupts the current avatar response. #### **Example Usage:** ```javascript theme={null} await agoraSDK.interrupt(); ``` ### **`getMessages(): Message[]`** Returns all chat messages in the current session. #### **Returns:** * `Message[]` - Array of chat messages #### **Example Usage:** ```javascript theme={null} const messages = agoraSDK.getMessages(); console.log("All messages:", messages); ``` ### **`getMessage(messageId: string): Message | undefined`** Returns a specific message by its ID. #### **Parameters:** * `messageId` (string) - The ID of the message to retrieve #### **Returns:** * `Message | undefined` - The message object or undefined if not found #### **Example Usage:** ```javascript theme={null} const message = agoraSDK.getMessage("msg-123"); if (message) { console.log("Message text:", message.text); } ``` *** ## **Audio Management** ### **`async toggleMic(): Promise`** Toggles the microphone on or off. #### **Example Usage:** ```javascript theme={null} await agoraSDK.toggleMic(); console.log("Microphone enabled:", agoraSDK.isMicEnabled()); ``` ### **`isMicEnabled(): boolean`** Checks if the microphone is currently enabled. #### **Returns:** * `boolean` - Microphone status #### **Example Usage:** ```javascript theme={null} const micEnabled = agoraSDK.isMicEnabled(); console.log("Microphone is:", micEnabled ? "on" : "off"); ``` *** ## **Client Access** ### **`getClient(): RTCClient`** Returns the underlying Agora RTC client instance for advanced operations. #### **Returns:** * `RTCClient` - The Agora RTC client #### **Example Usage:** ```javascript theme={null} const client = agoraSDK.getClient(); // Use client for advanced Agora operations ``` *** ## **Event Handling** ### **`on(events: SDKEvents): void`** Registers event handlers for various SDK events. #### **Parameters:** * `events` (SDKEvents) - Object containing event handler functions #### **Example Usage:** ```javascript theme={null} agoraSDK.on({ onStreamMessage: (uid, message) => { console.log(`Message from ${uid}:`, message); }, onException: (error) => { console.error("SDK Exception:", error); }, onMessageReceived: (message) => { console.log("New message received:", message); }, onMessageUpdated: (message) => { console.log("Message updated:", message); }, onNetworkStatsUpdated: (stats) => { console.log("Network stats updated:", stats); }, onTokenWillExpire: () => { console.warn("Token will expire in 30 seconds"); }, onTokenDidExpire: () => { console.error("Token has expired"); }, onUserPublished: async (user, mediaType) => { if (mediaType === 'video') { const remoteTrack = await agoraSDK.getClient().subscribe(user, mediaType); remoteTrack?.play('video-container-id'); } else if (mediaType === 'audio') { const remoteTrack = await agoraSDK.getClient().subscribe(user, mediaType); remoteTrack?.play(); } }, onUserUnpublished: (user, mediaType) => { console.log(`User ${user.uid} stopped publishing ${mediaType}`); } }); ``` *** ## **Type Definitions** ### **`AgoraCredentials`** Interface for Agora connection credentials. ```typescript theme={null} interface AgoraCredentials { agora_app_id: string; // Agora App ID agora_channel: string; // Channel name agora_token: string; // Agora token agora_uid: number; // User ID } ``` ### **`Metadata`** Interface for avatar configuration parameters. ```typescript theme={null} interface Metadata { vid?: string; // Voice ID vurl?: string; // Voice URL lang?: string; // Language code (e.g., "en", "es", "fr") mode?: number; // Mode type (1: repeat, 2: dialog) bgurl?: string; // Background image URL } ``` ### **`Message`** Interface for chat messages. ```typescript theme={null} interface Message { id: string; // Unique message ID text: string; // Message content isSentByMe: boolean; // Whether the message was sent by the current user } ``` ### **`NetworkStats`** Interface for network statistics. ```typescript theme={null} interface NetworkStats { localNetwork: NetworkQuality; // Local network quality remoteNetwork: NetworkQuality; // Remote network quality video: RemoteVideoTrackStats; // Video track statistics audio: RemoteAudioTrackStats; // Audio track statistics } ``` ### **`SDKEvents`** Interface defining all available event handlers. ```typescript theme={null} interface SDKEvents { onStreamMessage?: (uid: UID, message: StreamMessage) => void; onException?: (error: { code: number; msg: string; uid: UID }) => void; onNetworkQuality?: (stats: NetworkQuality) => void; onUserJoined?: (user: IAgoraRTCRemoteUser) => void; onUserLeft?: (user: IAgoraRTCRemoteUser, reason: string) => void; onRemoteAudioStats?: (stats: RemoteAudioTrackStats) => void; onRemoteVideoStats?: (stats: RemoteVideoTrackStats) => void; onTokenWillExpire?: () => void; onTokenDidExpire?: () => void; onMessageReceived?: (message: Message) => void; onMessageUpdated?: (message: Message) => void; onNetworkStatsUpdated?: (stats: NetworkStats) => void; onUserPublished?: (user: IAgoraRTCRemoteUser, mediaType: 'video' | 'audio' | 'datachannel') => void; onUserUnpublished?: (user: IAgoraRTCRemoteUser, mediaType: 'video' | 'audio' | 'datachannel') => void; } ``` *** ## **Complete Example** Here's a comprehensive example demonstrating how to use the SDK: ```javascript theme={null} import { GenericAgoraSDK } from 'akool-streaming-avatar-sdk'; // Initialize the SDK const agoraSDK = new GenericAgoraSDK({ mode: "rtc", codec: "vp8" }); // Set up event handlers agoraSDK.on({ onStreamMessage: (uid, message) => { console.log("Received message from", uid, ":", message); }, onException: (error) => { console.error("An exception occurred:", error); }, onMessageReceived: (message) => { console.log("New message:", message); // Update UI with new message updateMessageDisplay(message); }, onMessageUpdated: (message) => { console.log("Message updated:", message); // Update existing message in UI updateExistingMessage(message); }, onNetworkStatsUpdated: (stats) => { console.log("Network stats:", stats); // Update network quality indicator updateNetworkQuality(stats); }, onTokenWillExpire: () => { console.log("Token will expire in 30s"); // Refresh token from backend refreshToken(); }, onTokenDidExpire: () => { console.log("Token expired"); // Handle token expiration handleTokenExpiry(); }, onUserPublished: async (user, mediaType) => { if (mediaType === 'video') { const remoteTrack = await agoraSDK.getClient().subscribe(user, mediaType); remoteTrack?.play('remote-video-container'); } else if (mediaType === 'audio') { const remoteTrack = await agoraSDK.getClient().subscribe(user, mediaType); remoteTrack?.play(); } } }); // Function to initialize session async function initializeSession() { try { // Get session credentials from your backend const response = await fetch('/api/get-agora-credentials'); const credentials = await response.json(); // Join the Agora channel await agoraSDK.joinChannel({ agora_app_id: credentials.agora_app_id, agora_channel: credentials.agora_channel, agora_token: credentials.agora_token, agora_uid: credentials.agora_uid }); // Initialize avatar chat await agoraSDK.joinChat({ vid: "your-voice-id", lang: "en", mode: 2 }); console.log("Session initialized successfully"); } catch (error) { console.error("Failed to initialize session:", error); } } // Function to send a message async function sendMessage(content) { try { await agoraSDK.sendMessage(content); console.log("Message sent successfully"); } catch (error) { console.error("Failed to send message:", error); } } // Function to toggle microphone async function toggleMicrophone() { try { await agoraSDK.toggleMic(); const isEnabled = agoraSDK.isMicEnabled(); console.log("Microphone is now:", isEnabled ? "enabled" : "disabled"); updateMicButton(isEnabled); } catch (error) { console.error("Failed to toggle microphone:", error); } } // Function to clean up when leaving async function cleanup() { try { await agoraSDK.closeStreaming(); console.log("Session ended successfully"); } catch (error) { console.error("Error during cleanup:", error); } } // Initialize the session initializeSession(); ``` *** ## **Error Handling** The SDK provides comprehensive error handling through the `onException` event: ```javascript theme={null} agoraSDK.on({ onException: (error) => { console.error("SDK Error:", error.code, error.msg); // Handle specific error codes switch (error.code) { case 1001: // Handle authentication error handleAuthError(); break; case 1002: // Handle network error handleNetworkError(); break; default: // Handle other errors handleGenericError(error); } } }); ``` *** ## **Requirements** * Node.js 14 or higher (for development) * Modern browser with WebRTC support * Valid Agora credentials * Akool API access *** ## **Browser Support** * Chrome 56+ * Firefox 44+ * Safari 11+ * Edge 79+ * Opera 43+ *** ## **Additional Resources** * [Getting Started Guide](/sdk/jssdk-start) * [Best Practices](/sdk/jssdk-best-practice) * [NPM Package](https://www.npmjs.com/package/akool-streaming-avatar-sdk) * [GitHub Repository](https://github.com/akool-rinku/akool-streaming-avatar-sdk) * [Akool API Documentation](/authentication/usage) # Streaming Avatar SDK Best Practices Source: https://docs.akool.com/sdk/jssdk-best-practice Learn how to implement the Akool Streaming Avatar SDK securely and efficiently ## Overview This guide provides comprehensive best practices for implementing the [akool-streaming-avatar-sdk](https://www.npmjs.com/package/akool-streaming-avatar-sdk) package securely and efficiently. When implementing a JavaScript SDK that interacts with sensitive resources or APIs, it is critical to ensure the security of private keys, tokens, and other sensitive credentials. **Key Security Principles:** * Never expose private keys in client-side code * Use short-lived session tokens * Delegate authentication to a backend server * Implement proper error handling and logging * Follow secure coding practices for real-time communication **Package Information:** * [NPM Package](https://www.npmjs.com/package/akool-streaming-avatar-sdk) * [GitHub Repository](https://github.com/akool-rinku/akool-streaming-avatar-sdk) * **Current Version:** 1.0.6 ## Prerequisites * Get your [Akool API Token](https://www.akool.com) from [Akool Authentication API](/authentication/usage#get-the-token) * Basic knowledge of backend services and internet security * Understanding of JavaScript and HTTP requests * Node.js 14+ (for development) * Modern browser with WebRTC support ## Security Best Practices ### 1. Backend Session Management **❌ Never do this (Client-side token exposure):** ```javascript theme={null} // BAD: Exposing sensitive credentials on client const agoraSDK = new GenericAgoraSDK(); await agoraSDK.joinChannel({ agora_app_id: "YOUR_SENSITIVE_APP_ID", // ❌ Exposed agora_token: "YOUR_SENSITIVE_TOKEN", // ❌ Exposed agora_uid: 12345 }); ``` **✅ Do this instead (Secure backend delegation):** ```javascript theme={null} // GOOD: Get credentials from secure backend const credentials = await fetch('/api/secure/get-agora-session', { method: 'POST', headers: { 'Authorization': `Bearer ${userToken}` }, body: JSON.stringify({ userId, sessionType: 'avatar' }) }); const sessionData = await credentials.json(); await agoraSDK.joinChannel(sessionData.credentials); ``` ### 2. Backend Implementation Example Create secure endpoints in your backend to handle sensitive operations: ```javascript theme={null} // Backend: Node.js/Express example app.post('/api/secure/get-agora-session', authenticateUser, async (req, res) => { try { // Step 1: Get Akool access token const akoolToken = await getAkoolAccessToken(); // Step 2: Create avatar session const sessionData = await createAvatarSession(akoolToken, req.body); // Step 3: Return only necessary data to client res.json({ credentials: sessionData.credentials, sessionId: sessionData.id, expiresIn: sessionData.expires_in }); } catch (error) { res.status(500).json({ error: 'Session creation failed' }); } }); async function getAkoolAccessToken() { const response = await fetch('https://openapi.akool.com/api/open/v3/getToken', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ clientId: process.env.AKOOL_CLIENT_ID, // Server-side env var clientSecret: process.env.AKOOL_SECRET_KEY // Server-side env var }) }); const { data } = await response.json(); return data.token; } async function createAvatarSession(token, sessionConfig) { const response = await fetch('https://openapi.akool.com/api/open/v4/liveAvatar/session/create', { method: 'POST', headers: { 'x-api-key': '{{API Key}}' 'Content-Type': 'application/json' }, body: JSON.stringify({ avatar_id: sessionConfig.avatarId || "dvp_Tristan_cloth2_1080P", duration: sessionConfig.duration || 300 }) }); return await response.json(); } ``` 4. Sign up functions for steaming events and button click events: ```js theme={null} function handleStreamReady(event: any) { console.log("Stream is ready:", event.detail); } function handleMessageReceive(event: any) { console.log("Message:", event.detail); } function handleWillExpire(event: any) { console.log("Warning:", event.detail.msg); } function handleExpired(event: any) { console.log("Warning:", event.detail.msg); } function handleERROR(event: any) { console.error("ERROR has occurred:", event.detail.msg); } function handleStreamClose(event: any) { console.log("Stream is close:", event.detail); // when you leave the page you'd better off the eventhandler stream.off(StreamEvents.READY, handleStreamReady); stream.off(StreamEvents.ONMESSAGE, handleMessageReceive); stream.off(StreamEvents.WILLEXPIRE, handleWillExpire); stream.off(StreamEvents.EXPIRED, handleExpired); stream.off(StreamEvents.ERROR, handleERROR); stream.off(StreamEvents.CLOSED, handleStreamClose); } stream.on(StreamEvents.READY, handleStreamReady); stream.on(StreamEvents.ONMESSAGE, handleMessageReceive); stream.on(StreamEvents.WILLEXPIRE, handleWillExpire); stream.on(StreamEvents.EXPIRED, handleExpired); stream.on(StreamEvents.ERROR, handleERROR); stream.on(StreamEvents.CLOSED, handleStreamClose); async function handleToggleSession() { if ( window.toggleSession.innerHTML == "   ...   " ) return; if (window.toggleSession.innerHTML == "Start Session") { window.toggleSession.innerHTML = "   ...   "; await stream.startSessionWithCredentials( "yourStreamingVideoDom", paramsWithCredentials ); window.toggleSession.innerHTML = "End Session"; window.userInput.disabled = false; window.sendButton.disabled = false; window.voiceButton.disabled = false; } else { // info: close your stream session stream.closeStreaming(); window.messageWrap.innerHTML = ""; window.toggleSession.innerHTML = "Start Session"; window.userInput.disabled = true; window.sendButton.disabled = true; window.voiceButton.disabled = true; } } async function handleSendMessage() { await stream.sendMessage(window.userInput.value ?? ""); } async function handleToggleMic() { await stream.toggleMic(); if (stream.micStatus) { window.voiceButton.innerHTML = "Turn mic off"; } else { window.voiceButton.innerHTML = "Turn mic on"; } } window.toggleSession.addEventListener("click", handleToggleSession); window.sendButton.addEventListener("click", handleSendMessage); window.voiceButton.addEventListener("click", handleToggleMic); ``` ## Additional Resources * [Complete API Reference](/sdk/jssdk-api) - Detailed API documentation * [Getting Started Guide](/sdk/jssdk-start) - Quick start tutorial * [NPM Package](https://www.npmjs.com/package/akool-streaming-avatar-sdk) - Official package * [GitHub Repository](https://github.com/akool-rinku/akool-streaming-avatar-sdk) - Source code * [Akool Authentication API](/authentication/usage#get-the-token) - Authentication guide * [Error Codes Reference](/ai-tools-suite/error-code) - Error handling guide * [Live Avatar API](/ai-tools-suite/live-avatar#create-session) - Backend session creation # Streaming Avatar SDK Quick Start Source: https://docs.akool.com/sdk/jssdk-start Learn what is the Streaming Avatar SDK ## Overview The [Akool Streaming Avatar SDK](https://www.npmjs.com/package/akool-streaming-avatar-sdk) provides a generic JavaScript SDK for integrating Agora RTC streaming avatar functionality into any JavaScript application. This TypeScript-supported SDK enables programmatic control of avatar interactions with real-time video streaming capabilities. **Key Features:** * Easy-to-use API for Agora RTC integration * TypeScript support with full type definitions * Multiple bundle formats (ESM, CommonJS, IIFE) * CDN distribution via unpkg and jsDelivr * Event-based architecture for handling messages and state changes * Message management with history and updates * Network quality monitoring and statistics * Microphone control for voice interactions * Chunked message sending for large text * Automatic rate limiting for message chunks * Token expiry handling * Error handling and logging The integration uses Agora's Real-Time Communication (RTC) SDK for reliable, low-latency streaming and our avatar service for generating responsive avatar behaviors. ## Package Information * **NPM Package:** [akool-streaming-avatar-sdk](https://www.npmjs.com/package/akool-streaming-avatar-sdk) * **GitHub Repository:** [akool-rinku/akool-streaming-avatar-sdk](https://github.com/akool-rinku/akool-streaming-avatar-sdk) * **Current Version:** 1.0.6 * **License:** ISC ## Prerequisites * Get your [Akool API Token](https://www.akool.com) from [Akool Authentication API](/authentication/usage#get-the-token) * Basic knowledge of JavaScript and HTTP Requests * Modern browser with WebRTC support ## Browser Support The SDK requires a modern browser with WebRTC support, including: * Chrome 56+ * Firefox 44+ * Safari 11+ * Edge 79+ * Opera 43+ ## Installation ### NPM (Node.js/Modern JavaScript) ```bash theme={null} npm install akool-streaming-avatar-sdk ``` ### CDN (Browser) ```html theme={null} ``` ## Quick Start ### 1. HTML Setup Create a basic HTML page with a video container: ```html theme={null} Akool Streaming Avatar SDK

Streaming Avatar Demo

``` ### 2. Basic Usage with Modern JavaScript/TypeScript ```javascript theme={null} import { GenericAgoraSDK } from 'akool-streaming-avatar-sdk'; // Create an instance of the SDK const agoraSDK = new GenericAgoraSDK({ mode: "rtc", codec: "vp8" }); // Register event handlers agoraSDK.on({ onStreamMessage: (uid, message) => { console.log("Received message from", uid, ":", message); }, onException: (error) => { console.error("An exception occurred:", error); }, onMessageReceived: (message) => { console.log("New message:", message); }, onUserPublished: async (user, mediaType) => { if (mediaType === 'video') { const remoteTrack = await agoraSDK.getClient().subscribe(user, mediaType); remoteTrack?.play('remote-video'); // play the video in the div with id 'remote-video' } else if (mediaType === 'audio') { const remoteTrack = await agoraSDK.getClient().subscribe(user, mediaType); remoteTrack?.play(); } } }); // Get session info from your backend const akoolSession = await fetch('your-backend-url-to-get-session-info'); const { data: { credentials, id } } = await akoolSession.json(); // Join a channel await agoraSDK.joinChannel({ agora_app_id: credentials.agora_app_id, agora_channel: credentials.agora_channel, agora_token: credentials.agora_token, agora_uid: credentials.agora_uid }); // Initialize chat with avatar parameters await agoraSDK.joinChat({ vid: "voice-id", lang: "en", mode: 2 // 1 for repeat mode, 2 for dialog mode }); // Send a message await agoraSDK.sendMessage("Hello, world!"); ``` ### 3. Browser Usage (Global/IIFE) ```html theme={null} ``` ### 4. Quick Demo Result After following the setup, you'll have a working streaming avatar with real-time video and chat capabilities: * [Learn how to get your API token](/authentication/usage#get-the-token) * [Best practices for security and production usage](/sdk/jssdk-best-practice) ## Next Steps * [Complete API Reference](/sdk/jssdk-api) - Explore all available methods and events * [Best Practices Guide](/sdk/jssdk-best-practice) - Learn secure implementation patterns * [Create Live Avatar Session](/ai-tools-suite/live-avatar#create-session) - Backend session creation * [Error Codes Reference](/ai-tools-suite/error-code) - Handle errors effectively ## Additional Resources * [NPM Package](https://www.npmjs.com/package/akool-streaming-avatar-sdk) * [GitHub Repository](https://github.com/akool-rinku/akool-streaming-avatar-sdk) * [Akool OpenAPI Error Codes](/ai-tools-suite/live-avatar#response-code-description)