Last Updated on : 2025-08-05 03:12:17download
This topic describes how to query the chat history.
Query the chat history of an AI agent based on the device ID, bound role type, and role ID.
GET: /v1.0/cloud/agent/ai/enterprise/chat/devices/{device_id}/history
Parameter name | Type | Location | Required | Description |
---|---|---|---|---|
device_id | String | path | true | The ID of the specified device. |
gmt_end | Long | query | true | The timestamp when the chat message ends. Chat messages earlier than this time point will be returned. |
page_size | Integer | query | true | The number of items returned per page. Maximum value: 20. |
Parameter name | Type | Description |
---|---|---|
success | Boolean | Indicates whether the operation is successful. |
error_code | String | The error code. |
error_msg | String | The error message. |
result | Object | The returned result. |
Description of result
Parameter name | Type | Description |
---|---|---|
data | String | The chat information. It is encrypted and needs to be decrypted. |
pv | String | The protocol version. |
sign | String | The data signature for anti-counterfeiting verification. |
t | Long | The system time when the API returns a result. |
GET: /v1.0/cloud/agent/ai/enterprise/chat/devices/6c50600a0e15d1fb78h***/history?page_size=20&gmt_end=1753079987512
{
"error_msg": null,
"result": {
"data": "XpAnrVY93e***",
"pv": "1.0",
"sign": "e92b1036a7546f912058e07546ba66585ca2***",
"t": 1753770653706
},
"success": true,
"error_code": null
}
For more information, see Global Error Codes.
Description of data
in result
Parameter name | Type | Description |
---|---|---|
gmt_create | Long | The timestamp when the chat is created. |
answer | List | The list of answers. |
question | List | The list of questions. |
request_id | String | The ID of the chat history. |
role_info | Object | The role information. If a role is deleted, this parameter will not be returned. |
Description of answer/question objects
Parameter name | Type | Description |
---|---|---|
context | String | The message content. |
type | String | The message type. |
Description of the role_info
object
Parameter name | Type | Description |
---|---|---|
role_id | String | The ID of the specified role. |
role_name | String | The name of the specified role. |
bind_role_type | Integer | The type of role to bind. Valid values:
|
Sample of decrypted data
{
"data": [{
"answer": [{
"context": "You told me *** before",
"type": "text"
}],
"gmt_create": 1753758926504,
"question": [{
"context": "My ***",
"type": "text"
}],
"request_id": "ccbda733-e3d2-4ee3-bb19-d201-***",
"role_info": {
"bind_role_type": 1,
"role_id": "20001",
"role_name": "Test Role"
}
}]
}
To ensure data security, the chat history returned by the API is encrypted using AES-GCM authenticated encryption mode. You must decrypt the data
field in the response body to retrieve the original data.
Property | Description |
---|---|
Encryption standard | AES-GCM (Galois/Counter Mode). |
Key source | The Access Secret configured in the specified cloud development project. |
Security | Data integrity verification, authenticity authentication, and resistance to chosen-ciphertext attacks. |
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.security.InvalidKeyException;
import java.util.Base64;
public class CryptoUtils {
private static final String AES_ALGO = "AES";
private static final String AES_GCM = "AES/GCM/NoPadding";
private static final int GCM_NONCE_LENGTH = 12;
private static final int GCM_TAG_LENGTH = 16; // The authentication tag length
/**
* Implement AES-GCM decryption
*
* @param data: The Base64-encoded ciphertext string
* @param key: The project key, also known as Access Secret
* @return: The decrypted original string
* @throws IllegalArgumentException: Thrown if the input parameters are invalid
*/
public static String decryptDataGCM(String data, String key)
throws GeneralSecurityException {
// Parameter verification
if (key == null || key.isEmpty()) {
throw new IllegalArgumentException("Key cannot be null");
}
Key secretKey = new SecretKeySpec(key.getBytes(), AES_ALGO);
Cipher cipher = Cipher.getInstance(AES_GCM);
byte[] message = Base64.decodeBase64(data);
if (message.length < GCM_NONCE_LENGTH + GCM_TAG_LENGTH) {
throw new IllegalArgumentException();
}
GCMParameterSpec params = new GCMParameterSpec(GCM_TAG_LENGTH * 8, message, 0, GCM_NONCE_LENGTH);
cipher.init(Cipher.DECRYPT_MODE, secretKey, params);
byte[] decryptData = cipher.doFinal(message, GCM_NONCE_LENGTH, message.length - GCM_NONCE_LENGTH);
return new String(decryptData);
}
}
To ensure data integrity and the authenticity of the request source, please follow the following steps to verify the signature.
Get the data returned by the API. Extract the following important fields from the API response:
sign
: The digital signature returned by the API.t
: The Unix timestamp.pv
: The protocol version number.data
: The encrypted payload.Regenerate the signature locally. Calculate the signature using the same signature algorithm and key (Access Secret) as used by the API.
String localSign = SignUtils.createCloudSign(data, pv, t, accessSecret);
Verify the signature. Strictly compare the locally generated signature with the sign
value returned by the API.
if (!localSign.equals(apiSign)) {
// Handle verification failure
}
Validation result | Description | Action |
---|---|---|
Consistent | The data is complete and the source is trustworthy. | Data can be used safely. |
Inconsistent | Data was tampered with during transmission, or the key does not match. | 1. Discard current data. 2. Check key validity. 3. Trigger security alert mechanism. |
/**
* Generate a digital signature (SHA-256)
*
* @param data: The encrypted data, which must match the request content
* @param pv: The protocol version, such as '1.0'
* @param time: The timestamp, taken from the t parameter returned by the API
* @param secretKey: The project key, also known as Access Secret
* @return: The hexadecimal-encoded signature value
*/
public static String createCloudSign(String data,
String pv,
long time,
String secretKey)
throws NoSuchAlgorithmException {
// Parameter verification
if (secretKey == null || secretKey.isEmpty()) {
throw new IllegalArgumentException("secretKey cannot be null");
}
if (data == null || pv == null) {
throw new IllegalArgumentException("data and pv parameters cannot be null");
}
// Create an ordered set of parameters (By default, TreeMap is sorted in ascending order by key)
TreeMap<String, String> params = new TreeMap<>();
params.put("t", String.valueOf(time));
params.put("data", data);
params.put("pv", pv);
// Construct a signature string
StringBuilder sb = new StringBuilder(128);
for (Map.Entry<String, String> entry : params.entrySet()) {
String value = entry.getValue();
if (value != null && !value.trim().isEmpty()) {
sb.append(entry.getKey())
.append('=')
.append(value)
.append("||");
}
}
sb.append(secretKey);
// SHA-256 hash calculation
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(sb.toString().getBytes(StandardCharsets.UTF_8));
// Convert to hexadecimal
StringBuilder hexString = new StringBuilder(64);
for (byte b: hash) {
hexString.append(String.format("%02x", b));
}
return hexString.toString();
}
Is this page helpful?
YesFeedbackIs this page helpful?
YesFeedback