1.接口说明

人脸活体检测接口用于判断上传的人脸是否为真实活体,能够识别常见攻击方式(翻拍、视频、面具等),并返回活体分数与风险信息,可与人脸比对组合完成实名核身与风控。

1.1 主要功能

精准活体:
支持复杂光照、姿态,识别多种攻击载体。
快速响应:
云端计算,接口延迟低,适合实时业务。
简单接入:
提供多语言示例与双认证方式,快速上线。

1.2 典型场景

实名认证、线上开户、刷脸登录、防舞弊、远程监考、线上贷前风控等。

2.请求信息

2.1 请求地址(URL)

POST http(s)://face-api.shiliuai.com/api/face_liveness/v1

2.2 请求方式

POST

2.3 请求头(header)

参数 类型 说明
Content-Type string application/json
Authorization string 'APPCODE ' + 您的AppCode (注意英文空格)获取
参数 类型 说明
Content-Type string application/json
x-ca-key string 您的AppKey获取
x-ca-timestamp string 时间戳(毫秒)
x-ca-signature string 签名sign,md5(app_key&timestamp&app_secret)

2.4 请求体(body)

参数 是否必填 类型 说明
image_base64 必填其中之一 string 人脸图片Base64,像素[15,8192],小于20M
image_url string 人脸图片的url,像素[15,8192],小于20M
thresh float 活体阈值,默认0.8,分数大于阈值判为活体

3.返回信息

3.1 返回类型

JSON

3.2 返回码

参数名 类型 说明
code int 200表示成功
message string 返回信息

3.3 返回字段

参数 类型 说明
code int 错误码
msg string 错误信息(英文)
msg_cn string 错误信息(中文)
success bool 请求是否成功
request_id string 唯一请求ID
data object 活体检测结果

3.3.1 data 信息

参数 类型 说明 示例
liveness_score float 活体分数[0,1] 0.93
is_live bool 是否判定为活体(分数>阈值) true
risk_reason string 风险原因或为空 ""

3.4 返回示例

{
  "code": 200,
  "msg": "ok",
  "msg_cn": "成功",
  "success": true,
  "request_id": "c3f2b18e77",
  "data": {
    "liveness_score": 0.937,
    "is_live": true,
    "risk_reason": ""
  }
}

3.5 错误码

错误码 含义
4001 图片为空或格式错误
4002 未检测到人脸
4004 疑似翻拍或攻击,未通过活体
5000 服务内部错误,请稍后重试

4.示例代码

4.1 Python

import base64, json, requests

def get_b64(path):
    with open(path, "rb") as f:
        return base64.b64encode(f.read()).decode()

url = "https://face-api.shiliuai.com/api/face_liveness/v1"
headers = {
    "Authorization": "APPCODE 你的APPCODE",
    "Content-Type": "application/json"
}
body = {"image_base64": get_b64("face_live.jpg")}
print(requests.post(url, headers=headers, data=json.dumps(body), timeout=10).text)
import base64, json, requests, hashlib, time

def get_b64(path):
    with open(path, "rb") as f:
        return base64.b64encode(f.read()).decode()

def md5(s): return hashlib.md5(s.encode()).hexdigest()

url = "https://face-api.shiliuai.com/api/face_liveness/v1"
app_key = "你的APPKEY"
app_secret = "你的APPSECRET"
ts = str(int(time.time()*1000))
sign = md5(f"{app_key}&{ts}&{app_secret}")
headers = {
    "x-ca-key": app_key,
    "x-ca-timestamp": ts,
    "x-ca-signature": sign,
    "Content-Type": "application/json"
}
body = {"image_base64": get_b64("face_live.jpg")}
print(requests.post(url, headers=headers, data=json.dumps(body), timeout=10).text)

4.2 PHP

 get_base64("face_live.jpg")];
$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL => $url,
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => $headers,
    CURLOPT_POSTFIELDS => json_encode($data),
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_SSL_VERIFYPEER => false
]);
echo curl_exec($ch);
?>
 get_base64("face_live.jpg")];
$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL => $url,
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => $headers,
    CURLOPT_POSTFIELDS => json_encode($data),
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_SSL_VERIFYPEER => false
]);
echo curl_exec($ch);
?>

4.3 Java

import com.alibaba.fastjson2.JSONObject;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

public class FaceLiveEasy {
    static String getBase64(String path) throws Exception {
        return Base64.getEncoder().encodeToString(FileUtils.readFileToByteArray(new File(path)));
    }
    public static void main(String[] args) throws Exception {
        String url = "https://face-api.shiliuai.com/api/face_liveness/v1";
        Map headers = new HashMap<>();
        headers.put("Authorization","APPCODE 你的APPCODE");
        headers.put("Content-Type","application/json");
        JSONObject req = new JSONObject();
        req.put("image_base64", getBase64("face_live.jpg"));
        try(CloseableHttpClient client = HttpClients.createDefault()) {
            HttpPost post = new HttpPost(url);
            headers.forEach(post::addHeader);
            post.setEntity(new StringEntity(req.toJSONString(),"UTF-8"));
            HttpResponse resp = client.execute(post);
            System.out.println(EntityUtils.toString(resp.getEntity(),"UTF-8"));
        }
    }
}
import com.alibaba.fastjson2.JSONObject;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.security.MessageDigest;

public class FaceLiveSign {
    static String getBase64(String path) throws Exception {
        return Base64.getEncoder().encodeToString(FileUtils.readFileToByteArray(new File(path)));
    }
    static String md5(String s) throws Exception {
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] d = md.digest(s.getBytes("UTF-8"));
        StringBuilder sb = new StringBuilder();
        for(byte b:d) sb.append(String.format("%02x", b));
        return sb.toString();
    }
    public static void main(String[] args) throws Exception {
        String url = "https://face-api.shiliuai.com/api/face_liveness/v1";
        String appKey = "你的APPKEY";
        String appSecret = "你的APPSECRET";
        String ts = String.valueOf(System.currentTimeMillis());
        String sign = md5(appKey + "&" + ts + "&" + appSecret);
        Map headers = new HashMap<>();
        headers.put("x-ca-key", appKey);
        headers.put("x-ca-timestamp", ts);
        headers.put("x-ca-signature", sign);
        headers.put("Content-Type","application/json");
        JSONObject req = new JSONObject();
        req.put("image_base64", getBase64("face_live.jpg"));
        try(CloseableHttpClient client = HttpClients.createDefault()) {
            HttpPost post = new HttpPost(url);
            headers.forEach(post::addHeader);
            post.setEntity(new StringEntity(req.toJSONString(),"UTF-8"));
            HttpResponse resp = client.execute(post);
            System.out.println(EntityUtils.toString(resp.getEntity(),"UTF-8"));
        }
    }
}

4.4 JavaScript

// 需 Node.js 18+(内置 fetch)
const fs = require('fs');

const apiUrl = 'https://face-api.shiliuai.com/api/face_liveness/v1';
const appcode = '你的APPCODE';
const filePath = 'face_live.jpg';

async function main() {
  const imageBase64 = fs.readFileSync(filePath).toString('base64');

  const res = await fetch(apiUrl, {
    method: 'POST',
    headers: {
      Authorization: 'APPCODE ' + appcode,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ image_base64: imageBase64 })
  });

  const text = await res.text();
  console.log(text);
}

main().catch(console.error);
// 需 Node.js 18+(内置 fetch)
const fs = require('fs');
const crypto = require('crypto');

const apiUrl = 'https://face-api.shiliuai.com/api/face_liveness/v1';
const filePath = 'face_live.jpg';
const appKey = '你的APPKEY';
const appSecret = '你的APPSECRET';
const timestamp = Date.now().toString();
const signHex = crypto.createHash('md5').update(appKey + '&' + timestamp + '&' + appSecret).digest('hex');

async function main() {
  const imageBase64 = fs.readFileSync(filePath).toString('base64');

  const res = await fetch(apiUrl, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-ca-key': appKey,
      'x-ca-timestamp': timestamp,
      'x-ca-signature': signHex
    },
    body: JSON.stringify({ image_base64: imageBase64 })
  });

  const text = await res.text();
  console.log(text);
}

main().catch(console.error);

4.5 C#

using System;
using System.Net.Http;
using System.Text;
using Newtonsoft.Json.Linq;
using System.IO;

class FaceLiveEasy {
    static string GetBase64(string path) => Convert.ToBase64String(File.ReadAllBytes(path));
    static async System.Threading.Tasks.Task Main() {
        var url = "https://face-api.shiliuai.com/api/face_liveness/v1";
        var client = new HttpClient();
        client.DefaultRequestHeaders.Add("Authorization","APPCODE 你的APPCODE");
        var body = new JObject { ["image_base64"] = GetBase64("face_live.jpg") }.ToString();
        var resp = await client.PostAsync(url, new StringContent(body, Encoding.UTF8, "application/json"));
        Console.WriteLine(await resp.Content.ReadAsStringAsync());
    }
}
using System;
using System.Net.Http;
using System.Text;
using Newtonsoft.Json.Linq;
using System.IO;
using System.Security.Cryptography;

class FaceLiveSign {
    static string GetBase64(string path) => Convert.ToBase64String(File.ReadAllBytes(path));
    static string Md5(string s){
        using var md5 = MD5.Create();
        var bytes = md5.ComputeHash(Encoding.UTF8.GetBytes(s));
        var sb = new StringBuilder();
        foreach(var b in bytes) sb.Append(b.ToString("x2"));
        return sb.ToString();
    }
    static async System.Threading.Tasks.Task Main() {
        var url = "https://face-api.shiliuai.com/api/face_liveness/v1";
        var appKey = "你的APPKEY";
        var appSecret = "你的APPSECRET";
        var ts = DateTimeOffset.Now.ToUnixTimeMilliseconds().ToString();
        var sign = Md5($"{appKey}&{ts}&{appSecret}");
        var client = new HttpClient();
        client.DefaultRequestHeaders.Add("x-ca-key", appKey);
        client.DefaultRequestHeaders.Add("x-ca-timestamp", ts);
        client.DefaultRequestHeaders.Add("x-ca-signature", sign);
        var body = new JObject { ["image_base64"] = GetBase64("face_live.jpg") }.ToString();
        var resp = await client.PostAsync(url, new StringContent(body, Encoding.UTF8, "application/json"));
        Console.WriteLine(await resp.Content.ReadAsStringAsync());
    }
}

4.6 易语言

版本 2
.支持库 spec
.支持库 dp1

.子程序 OCR_简单认证
.局部变量 局_网址, 文本型
.局部变量 局_提交数据, 文本型
.局部变量 局_提交协议头, 文本型
.局部变量 局_结果, 字节集
.局部变量 局_返回, 文本型
.局部变量 图片数据, 字节集
.局部变量 base64图片, 文本型

图片数据 = 读入文件 ("你的文件路径")
base64图片 = 编码_BASE64编码 (图片数据)
局_提交数据 = "{" + #引号 + "image_base64" + #引号 + ":" + #引号 + base64图片 + #引号 + "}"
局_网址 = "https://face-api.shiliuai.com/api/face_liveness/v1"
局_提交协议头 = "Authorization: APPCODE 你的AppCode" + #换行符 + "Content-Type: application/json"
局_结果 = 网页_访问_对象 (局_网址, 1, 局_提交数据, , , 局_提交协议头, , , , , , , , , , , , , )
局_返回 = 到文本 (编码_编码转换对象 (局_结果, , , ))
返回 (局_返回)
版本 2
.支持库 spec
.支持库 dp1

.子程序 OCR_签名认证
.参数 app_key, 文本型
.参数 app_secret, 文本型
.参数 文件路径, 文本型
.局部变量 局_网址, 文本型
.局部变量 局_提交数据, 文本型
.局部变量 局_提交协议头, 文本型
.局部变量 局_结果, 字节集
.局部变量 局_返回, 文本型
.局部变量 文件数据, 字节集
.局部变量 base64文件, 文本型
.局部变量 时间戳, 文本型
.局部变量 签名字符串, 文本型
.局部变量 签名, 文本型

文件数据 = 读入文件 (文件路径)
base64文件 = 编码_BASE64编码 (文件数据)
时间戳 = 到文本 (时间_取时间戳 () * 1000)
签名字符串 = app_key + "&" + 时间戳 + "&" + app_secret
签名 = 到十六进制文本 (编码_MD5摘要 (到字节集 (签名字符串)))

局_提交数据 = "{" + #引号 + "image_base64" + #引号 + ":" + #引号 + base64文件 + #引号 + "}"
局_网址 = "https://face-api.shiliuai.com/api/face_liveness/v1"
局_提交协议头 = "x-ca-key: " + app_key + #换行符 + "x-ca-timestamp: " + 时间戳 + #换行符 + "x-ca-signature: " + 签名 + #换行符 + "Content-Type: application/json"
局_结果 = 网页_访问_对象 (局_网址, 1, 局_提交数据, , , 局_提交协议头, , , , , , , , , , , , , )
局_返回 = 到文本 (编码_编码转换对象 (局_结果, , , ))
返回 (局_返回)

4.7 天诺

public static string OCR_Easy(Image image, string appcode)
{
    string url = "https://face-api.shiliuai.com/api/face_liveness/v1";
    var headers = new Dictionary<string, string>
    {
        {"Authorization", "APPCODE " + appcode},
        {"Content-Type", "application/json"}
    };
    string body = "{\"image_base64\":\"" + CustomHelp.ImageTobase64(image) + "\"}";
    return CustomHelp.HttpPost(url, body, headers);
}
public static string app_key = "你的APPKEY";
public static string app_secret = "你的APPSECRET";

public static string GetTimestampMs()
{
    return DateTimeOffset.Now.ToUnixTimeMilliseconds().ToString();
}

public static string MD5(string input)
{
    using (var md5 = System.Security.Cryptography.MD5.Create())
    {
        var bytes = System.Text.Encoding.UTF8.GetBytes(input);
        var hash = md5.ComputeHash(bytes);
        var sb = new System.Text.StringBuilder();
        foreach (var b in hash) sb.Append(b.ToString("x2"));
        return sb.ToString();
    }
}

public static string OCR_Sign(Image image)
{
    string url = "https://face-api.shiliuai.com/api/face_liveness/v1";
    string timestamp = GetTimestampMs();
    string sign = MD5(app_key + "&" + timestamp + "&" + app_secret);

    var headers = new Dictionary<string, string>
    {
        {"x-ca-key", app_key},
        {"x-ca-timestamp", timestamp},
        {"x-ca-signature", sign},
        {"Content-Type", "application/json"}
    };

    string body = "{\"image_base64\":\"" + CustomHelp.ImageTobase64(image) + "\"}";
    return CustomHelp.HttpPost(url, body, headers);
}

4.8 按键精灵-电脑版

Import "Encrypt.dll"
VBSBegin
Function Base64Encode(filePath)
    Set inStream = CreateObject("ADODB.Stream")
    inStream.Type = 1
    inStream.Open
    inStream.LoadFromFile filePath
    inStream.Position = 0
    Set dom = CreateObject("MSXML2.DOMDocument")
    Set elem = dom.createElement("tmp")
    elem.dataType = "bin.base64"
    elem.nodeTypedValue = inStream.Read
    Base64Encode = elem.Text
    inStream.Close
End Function

Function ocr_easy(appcode, imgPath)
    url = "https://face-api.shiliuai.com/api/face_liveness/v1"
    jsonBody = "{\"image_base64\":\"" & Base64Encode(imgPath) & "\"}"
    Set http = CreateObject("MSXML2.XMLHTTP")
    http.Open "POST", url, False
    http.setRequestHeader "Authorization", "APPCODE " & appcode
    http.setRequestHeader "Content-Type", "application/json"
    http.send jsonBody
    ocr_easy = http.responseText
End Function
VBSEnd

appcode = "你的APPCODE"
res = ocr_easy(appcode, "你的文件路径")
TracePrint res
Import "Encrypt.dll"
VBSBegin
Function MD5(str)
    MD5 = LCase(Encrypt.Md5String(str))
End Function

Function Base64Encode(filePath)
    Set inStream = CreateObject("ADODB.Stream")
    inStream.Type = 1
    inStream.Open
    inStream.LoadFromFile filePath
    inStream.Position = 0
    Set dom = CreateObject("MSXML2.DOMDocument")
    Set elem = dom.createElement("tmp")
    elem.dataType = "bin.base64"
    elem.nodeTypedValue = inStream.Read
    Base64Encode = elem.Text
    inStream.Close
End Function

Function ocr_sign(appKey, appSecret, imgPath)
    url = "https://face-api.shiliuai.com/api/face_liveness/v1"
    timestamp = CStr(DateDiff("s", "01/01/1970 00:00:00", Now()) * 1000)
    signature = MD5(appKey & "&" & timestamp & "&" & appSecret)
    jsonBody = "{\"image_base64\":\"" & Base64Encode(imgPath) & "\"}"
    Set http = CreateObject("MSXML2.XMLHTTP")
    http.Open "POST", url, False
    http.setRequestHeader "x-ca-key", appKey
    http.setRequestHeader "x-ca-timestamp", timestamp
    http.setRequestHeader "x-ca-signature", signature
    http.setRequestHeader "Content-Type", "application/json"
    http.send jsonBody
    ocr_sign = http.responseText
End Function
VBSEnd

appKey = "你的APPKEY"
appSecret = "你的APPSECRET"
res = ocr_sign(appKey, appSecret, "你的文件路径")
TracePrint res

4.9 按键精灵-手机版

Import "yd.luae"
Import "zm.luae"

Dim imagePath = "/sdcard/Pictures/test.png"
SnapShotEx imagePath

Function ocr_easy(appcode, imagePath)
    Dim url = "https://face-api.shiliuai.com/api/face_liveness/v1"
    Dim body = "{\"image_base64\":\"" & yd.Base64EncodeFile(imagePath) & "\"}"
    Dim headers = {null}
    headers["Authorization"] = "APPCODE " & appcode
    headers["Content-Type"] = "application/json"
    Dim res = yd.HttpPost(url, body, headers)
    ocr_easy = yd.JsonDecode(res)
End Function

Dim appcode = "你的 APPCODE"
Dim t1 = TickCount()
Dim res = ocr_easy(appcode, imagePath)
Dim t2 = TickCount()
TracePrint res["code"]
Import "yd.luae"
Import "zm.luae"

Dim imagePath = "/sdcard/Pictures/test.png"
SnapShotEx imagePath

Dim appKey = "你的 APPKEY"
Dim appSecret = "你的 APPSECRET"

Function ocr_sign(appKey, appSecret, imagePath)
    Dim url = "https://face-api.shiliuai.com/api/face_liveness/v1"
    Dim timestamp = CStr(os.time()*1000)
    Dim signature = Encode.Md5(appKey & "&" & timestamp & "&" & appSecret)
    Dim body = "{\"image_base64\":\"" & yd.Base64EncodeFile(imagePath) & "\"}"
    Dim headers = {null}
    headers["x-ca-key"] = appKey
    headers["x-ca-timestamp"] = timestamp
    headers["x-ca-signature"] = signature
    headers["Content-Type"] = "application/json"
    Dim res = yd.HttpPost(url, body, headers)
    ocr_sign = yd.JsonDecode(res)
End Function

Dim t1 = TickCount()
Dim res = ocr_sign(appKey, appSecret, imagePath)
Dim t2 = TickCount()
TracePrint res["code"]

4.10 触动精灵

require("tsnet")
require "TSLib"
local ts = require("ts")
local json = ts.json

function readFileBase64(path)
    local f = io.open(path,"rb")
    if not f then return nil end
    local bytes = f:read("*all")
    f:close()
    return bytes:base64_encode()
end

function ocr_easy(appcode, imagePath)
    local url = "https://face-api.shiliuai.com/api/face_liveness/v1"
    local body = json.encode({ image_base64 = readFileBase64(imagePath) })
    local headers = {}
    headers["Authorization"] = "APPCODE " .. appcode
    headers["Content-Type"] = "application/json"
    local resp = httpPost(url, body, { headers = headers })
    return json.decode(resp)
end
require("tsnet")
require "TSLib"
local ts = require("ts")
local json = ts.json

function readFileBase64(path)
    local f = io.open(path,"rb")
    if not f then return nil end
    local bytes = f:read("*all")
    f:close()
    return bytes:base64_encode()
end

function ocr_sign(appKey, appSecret, imagePath)
    local url = "https://face-api.shiliuai.com/api/face_liveness/v1"
    local timestamp = tostring(os.time()*1000)
    local signature = (appKey.."&"..timestamp.."&"..appSecret):md5()
    local body = json.encode({ image_base64 = readFileBase64(imagePath) })
    local headers = {}
    headers["x-ca-key"] = appKey
    headers["x-ca-timestamp"] = timestamp
    headers["x-ca-signature"] = signature
    headers["Content-Type"] = "application/json"
    local resp = httpPost(url, body, { headers = headers })
    return json.decode(resp)
end

4.11 懒人精灵

function ocr_easy(appcode, imagePath)
    local url = "https://face-api.shiliuai.com/api/face_liveness/v1"
    local body = jsonLib.encode({ image_base64 = getFileBase64(imagePath) })
    local headers = {}
    headers["Authorization"] = "APPCODE " .. appcode
    headers["Content-Type"] = "application/json"
    local resp = httpPost(url, body, { headers = headers })
    return jsonLib.decode(resp)
end
function ocr_sign(appKey, appSecret, imagePath)
    local url = "https://face-api.shiliuai.com/api/face_liveness/v1"
    local timestamp = tostring(os.time()*1000)
    local signature = MD5(appKey.."&"..timestamp.."&"..appSecret)
    local body = jsonLib.encode({ image_base64 = getFileBase64(imagePath) })
    local headers = {}
    headers["x-ca-key"] = appKey
    headers["x-ca-timestamp"] = timestamp
    headers["x-ca-signature"] = signature
    headers["Content-Type"] = "application/json"
    local resp = httpPost(url, body, { headers = headers })
    return jsonLib.decode(resp)
end

4.12 EasyClick

function main()
    local request = image.requestScreenCapture(10000, 0)
    if not request then
        request = image.requestScreenCapture(10000, 0)
    end
    local appCode = "你的 APPCODE"
    local img = image.captureFullScreenEx()
    local res = ocr_easy(appCode, img)
    logd(res.code)
end

function ocr_easy(appCode, img)
    local url = "https://face-api.shiliuai.com/api/face_liveness/v1"
    local imgBase64 = image.toBase64Format(img, "jpg", 100)
    image.recycle(img)
    local body = JSON.stringify({ image_base64 = imgBase64 })
    local params = {
        url = url,
        method = "POST",
        headers = {
            ["Authorization"] = "APPCODE " .. appCode,
            ["Content-Type"] = "application/json"
        },
        requestBody = body
    }
    local res = http.request(params)
    return JSON.parse(res.body)
end
function main()
    local request = image.requestScreenCapture(10000, 0)
    if not request then
        request = image.requestScreenCapture(10000, 0)
    end
    local appKey = "你的 APPKEY"
    local appSecret = "你的 APPSECRET"
    local img = image.captureFullScreenEx()
    local res = ocr_sign(appKey, appSecret, img)
    logd(res.code)
end

function ocr_sign(appKey, appSecret, img)
    local url = "https://face-api.shiliuai.com/api/face_liveness/v1"
    local imgBase64 = image.toBase64Format(img, "jpg", 100)
    local timestamp = tostring(os.time() * 1000)
    local signature = utils.dataMd5(appKey .. "&" .. timestamp .. "&" .. appSecret)
    image.recycle(img)
    local body = JSON.stringify({ image_base64 = imgBase64 })
    local params = {
        url = url,
        method = "POST",
        headers = {
            ["x-ca-key"] = appKey,
            ["x-ca-timestamp"] = timestamp,
            ["x-ca-signature"] = signature,
            ["Content-Type"] = "application/json"
        },
        requestBody = body
    }
    local res = http.request(params)
    return JSON.parse(res.body)
end