Query Chat History

Last Updated on : 2026-02-26 09:17:39Copy for LLMView as MarkdownDownload PDF

Query the chat history of an AI agent based on the device ID, bound role type, and role ID.

API address

GET: /v1.0/cloud/agent/ai/enterprise/chat/devices/{device_id}/history

Request parameter

Parameter nameTypeINRequiredDescription
device_idStringpathtrueThe ID of the specified device.
gmt_endLongquerytrueThe timestamp when the chat message ends. Chat messages earlier than this time point will be returned.
page_sizeIntegerquerytrueThe number of items returned per page. Maximum value: 20.

Return parameter

Parameter nameTypeDescription
successBooleanIndicates whether the operation is successful.
error_codeStringThe error code.
error_msgStringThe error message.
resultObjectThe returned result.

Description of result

Parameter nameTypeDescription
dataStringThe chat information. It is encrypted and needs to be decrypted.
pvStringThe protocol version.
signStringThe data signature for anti-counterfeiting verification.
tLongThe system time when the API returns a result.

Request example

GET: /v1.0/cloud/agent/ai/enterprise/chat/devices/6c50600a0e15d1fb78h***/history?page_size=20&gmt_end=1753079987512

Return example

{
    "error_msg": null,
    "result": {
        "data": "XpAnrVY93e***",
        "pv": "1.0",
        "sign": "e92b1036a7546f912058e07546ba66585ca2***",
        "t": 1753770653706
    },
    "success": true,
    "error_code": null
}

Error code

For more information, see error code.

Decrypted return values

Description of data object in result

Parameter nameTypeDescription
gmt_createLongThe timestamp when the chat was created.
answerListThe list of answers.
questionListThe list of questions.
request_idStringThe ID of the chat history.
role_infoObjectThe role information. If a role is deleted, this parameter will not be returned.

Description of answer/question objects

Parameter nameTypeDescription
contextStringThe message content.
typeStringThe message type.

Description of the role_info object

Parameter nameTypeDescription
role_idStringThe role ID.
role_nameStringThe role name.
bind_role_typeIntegerThe type of role to bind. Valid values: 0: Custom agent role. 1: Agent role template. 2: Default role for single-role scenarios.

Decrypted data example

{
	"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"
		}
	}]
}

Chat history decryption mechanism

Functional description

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.

Technical specifications

PropertySpecification
Encryption standardAES-GCM (Galois/Counter Mode).
Key sourceAccess Secret configured in the specified cloud development project.

Java implementation example

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);
    }
}

Signature generation specifications

To ensure data integrity and the authenticity of the request source, please follow the following steps to verify the signature.

Signature generation rules

  1. Step 1: 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.

  2. Step 2: 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);
    
  3. Step 3: Verify the signature
    Strictly compare the locally generated signature with the sign value returned by the API.

Java implementation example

    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");
        }

        TreeMap<String, String> params = new TreeMap<>();
        params.put("t", String.valueOf(time));
        params.put("data", data);
        params.put("pv", pv);

        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);

        MessageDigest digest = MessageDigest.getInstance("SHA-256");
        byte[] hash = digest.digest(sb.toString().getBytes(StandardCharsets.UTF_8));
        
        StringBuilder hexString = new StringBuilder(64);
        for (byte b: hash) {
            hexString.append(String.format("%02x", b));
        }
	return hexString.toString();
}