All Products
Search
Document Center

Intelligent Speech Interaction:Obtain a token using OpenAPI

Last Updated:Sep 28, 2026

Use OpenAPI to obtain a token when an SDK is unavailable for the programming language or when dependencies need to be managed directly. This topic describes the request parameters, signature mechanism, and response format, and provides Java and Python examples.

Prepare credentials

The API requires an AccessKey ID and AccessKey secret. Set the ALIYUN_AK_ID and ALIYUN_AK_SECRET environment variables in the runtime environment. The examples read credentials from these variables.

Important

AccessKey secrets and tokens are sensitive information. Do not include them in public code or logs. The following examples print the response, which contains a token. Protect this information when integrating the code into an application.

Code examples

The following examples obtain a token by sending an HTTPS GET request. In the response, Token.Id is the token value and Token.ExpireTime is its expiration timestamp in seconds.

Java

Use JDK 8 or later and add the following Maven dependency.

<dependency>
    <groupId>com.squareup.okhttp3</groupId>
    <artifactId>okhttp</artifactId>
    <version>3.9.1</version>
</dependency>
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Base64;
import java.util.Map;
import java.util.StringJoiner;
import java.util.TreeMap;
import java.util.UUID;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class CreateToken {
    private static String encode(String value) throws Exception {
        return URLEncoder.encode(value, "UTF-8")
                .replace("+", "%20").replace("*", "%2A").replace("%7E", "~");
    }

    public static void main(String[] args) throws Exception {
        String accessKeyId = System.getenv("ALIYUN_AK_ID");
        String accessKeySecret = System.getenv("ALIYUN_AK_SECRET");
        if (accessKeyId == null || accessKeyId.isEmpty()
                || accessKeySecret == null || accessKeySecret.isEmpty()) {
            throw new IllegalArgumentException("Set ALIYUN_AK_ID and ALIYUN_AK_SECRET.");
        }

        String endpoint = "https://nlsmeta.ap-southeast-1.aliyuncs.com/";
        Map<String, String> parameters = new TreeMap<>();
        parameters.put("AccessKeyId", accessKeyId);
        parameters.put("Action", "CreateToken");
        parameters.put("Version", "2019-07-17");
        parameters.put("RegionId", "ap-southeast-1");
        parameters.put("Format", "JSON");
        parameters.put("SignatureMethod", "HMAC-SHA1");
        parameters.put("SignatureVersion", "1.0");
        parameters.put("SignatureNonce", UUID.randomUUID().toString());
        parameters.put("Timestamp", Instant.now().truncatedTo(ChronoUnit.SECONDS).toString());

        StringJoiner query = new StringJoiner("&");
        for (Map.Entry<String, String> entry : parameters.entrySet()) {
            query.add(encode(entry.getKey()) + "=" + encode(entry.getValue()));
        }
        String canonicalQuery = query.toString();
        String stringToSign = "GET&" + encode("/") + "&" + encode(canonicalQuery);
        Mac mac = Mac.getInstance("HmacSHA1");
        mac.init(new SecretKeySpec((accessKeySecret + "&").getBytes(StandardCharsets.UTF_8), "HmacSHA1"));
        String signature = Base64.getEncoder().encodeToString(
                mac.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8)));

        Request request = new Request.Builder()
                .url(endpoint + "?" + canonicalQuery + "&Signature=" + encode(signature))
                .get().build();
        OkHttpClient client = new OkHttpClient();
        try (Response response = client.newCall(request).execute()) {
            String body = response.body() == null ? "" : response.body().string();
            if (!response.isSuccessful()) {
                throw new IllegalStateException("HTTP " + response.code() + ": " + body);
            }
            System.out.println(body);
        }
    }
}

Python

Use Python 3.4 or later and install Requests. The example uses Python 3.14.7.

pip install requests
import base64
import hashlib
import hmac
import os
import uuid
from datetime import datetime, timezone
from urllib.parse import quote

import requests


def encode(value):
    return quote(value, safe="-_.~")


def create_token():
    access_key_id = os.environ["ALIYUN_AK_ID"]
    access_key_secret = os.environ["ALIYUN_AK_SECRET"]
    endpoint = "https://nlsmeta.ap-southeast-1.aliyuncs.com/"
    parameters = {
        "AccessKeyId": access_key_id,
        "Action": "CreateToken",
        "Version": "2019-07-17",
        "RegionId": "ap-southeast-1",
        "Format": "JSON",
        "SignatureMethod": "HMAC-SHA1",
        "SignatureVersion": "1.0",
        "SignatureNonce": str(uuid.uuid4()),
        "Timestamp": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"),
    }
    canonical_query = "&".join(
        encode(key) + "=" + encode(value)
        for key, value in sorted(parameters.items())
    )
    string_to_sign = "GET&" + encode("/") + "&" + encode(canonical_query)
    signature = base64.b64encode(hmac.new(
        (access_key_secret + "&").encode("utf-8"),
        string_to_sign.encode("utf-8"), hashlib.sha1
    ).digest()).decode("ascii")
    response = requests.get(
        endpoint + "?" + canonical_query + "&Signature=" + encode(signature),
        timeout=20,
    )
    if response.status_code != 200:
        raise RuntimeError("HTTP {}: {}".format(response.status_code, response.text))
    return response.text


if __name__ == "__main__":
    print(create_token())

Request details

The API supports GET and POST and uses Alibaba Cloud POP request signing. HTTP and HTTPS requests use the same parameters. HTTPS is recommended.

Endpoint

Endpoint: https://nlsmeta.ap-southeast-1.aliyuncs.com/. RegionId: ap-southeast-1. API version: 2019-07-17.

Request parameters

Name

Type

Required

Description

AccessKeyId

String

Yes

The AccessKey ID.

Action

String

Yes

The operation name. Set this parameter to CreateToken.

Version

String

Yes

The API version. Set this parameter to 2019-07-17.

Format

String

No

The response format. Set this parameter to JSON for a JSON response. If omitted, the response is XML. The examples in this topic use JSON.

RegionId

String

Yes

The region ID. Set this parameter to ap-southeast-1.

Timestamp

String

Yes

The request timestamp in UTC, in the yyyy-MM-dd'T'HH:mm:ss'Z' format. Example: 2019-04-03T06:15:03Z. Use the current time for an actual request.

SignatureMethod

String

Yes

The signature algorithm. Set this parameter to HMAC-SHA1.

SignatureVersion

String

Yes

The signature algorithm version. Set this parameter to 1.0.

SignatureNonce

String

Yes

A unique random string to prevent replay attacks. Use a different value for each request. A UUID such as 8d1e6a7a-f44e-40d5-aedb-fe4a1c80f434 can be used.

Signature

String

Yes

The signature calculated from all request parameters except Signature. See the signature mechanism below.

Headers and parameter placement

For GET, place the parameters in the URL query string. For POST, place them in the request body.

Header

Required

Description

Host

No

The service hostname. The HTTP client typically sets this header based on the endpoint.

Accept

No

Set this header to application/json to indicate that the client accepts JSON. The usual default is */*. Use the Format parameter to specify the response format.

Content-Type

Required for POST

Set this header to application/x-www-form-urlencoded for POST requests.

The following templates show the request format. <encoded-parameters> represents the URL-encoded parameter string, including Signature. When signing a POST request, use POST as the HTTP method. A GET signature cannot be reused for POST.

GET

GET /?<encoded-parameters> HTTP/1.1
Host: <endpoint-host>
Accept: application/json

POST

POST / HTTP/1.1
Host: <endpoint-host>
Accept: application/json
Content-Type: application/x-www-form-urlencoded

<encoded-parameters>

Signature mechanism

Every request must include a signature. The client uses the AccessKey secret to calculate an HMAC-SHA1 message authentication code. The server retrieves the corresponding secret based on the AccessKey ID and verifies the signature to authenticate the caller and check request integrity.

Construct the canonicalized query string

  1. Exclude the Signature parameter and sort the remaining parameters by name in case-sensitive lexicographical order.

  2. URL-encode each parameter name and value using UTF-8:

    • Do not encode A-Z, a-z, 0-9, -, _, ., or ~.

    • Encode other characters as %XY for each UTF-8 byte. For example, encode a double quotation mark as %22.

    • Encode spaces as %20, not as a plus sign (+).

  3. Join each encoded name and value with =, and join the resulting pairs with &. Do not place & before the first parameter.

percentEncode(name1)=percentEncode(value1)&percentEncode(name2)=percentEncode(value2)

Java's URLEncoder uses form encoding. In its output, replace + with %20, * with %2A, and %7E with ~.

Construct the string to sign

Join the uppercase HTTP method, the encoded request path (/), and the encoded canonicalized query string with &.

StringToSign = HTTPMethod + "&" + percentEncode("/") + "&" + percentEncode(CanonicalizedQueryString)

Calculate and add the signature

  1. Append & to the AccessKey secret to form the HMAC-SHA1 key.

  2. Encode the key and string to sign in UTF-8, calculate the HMAC-SHA1 value, and Base64-encode the result.

  3. URL-encode the Base64 result and add it to the request parameters as Signature=<encoded-signature>.

Signature = Base64(HMAC-SHA1(AccessKeySecret + "&", StringToSign))

Signature verification example

Use the following fixed parameters to check a signing implementation offline. The AccessKey pair is fictitious and the timestamp has expired, so these values cannot be used to obtain a token.

AccessKeyId: my_access_key_id
AccessKeySecret: my_access_key_secret
Action: CreateToken
Format: JSON
SignatureMethod: HMAC-SHA1
SignatureVersion: 1.0
SignatureNonce: b924c8c3-6d03-4c5d-ad36-d984d3116788
Timestamp: 2019-04-18T08:32:31Z
HTTPMethod: GET

Canonicalized query string:

AccessKeyId=my_access_key_id&Action=CreateToken&Format=JSON&RegionId=ap-southeast-1&SignatureMethod=HMAC-SHA1&SignatureNonce=b924c8c3-6d03-4c5d-ad36-d984d3116788&SignatureVersion=1.0&Timestamp=2019-04-18T08%3A32%3A31Z&Version=2019-07-17

String to sign:

GET&%2F&AccessKeyId%3Dmy_access_key_id%26Action%3DCreateToken%26Format%3DJSON%26RegionId%3Dap-southeast-1%26SignatureMethod%3DHMAC-SHA1%26SignatureNonce%3Db924c8c3-6d03-4c5d-ad36-d984d3116788%26SignatureVersion%3D1.0%26Timestamp%3D2019-04-18T08%253A32%253A31Z%26Version%3D2019-07-17

Base64 signature:

4TdrOuLHXJU+5C6s927Wkq2h+wc=

URL-encoded signature parameter:

Signature=4TdrOuLHXJU%2B5C6s927Wkq2h%2Bwc%3D

Response details

The following descriptions apply when Format=JSON. GET and POST requests use the same response format.

Successful response

The HTTP status code is 200. The main fields are as follows.

Field

Type

Description

Token

Object

Contains the token value and expiration time.

Token.Id

String

The token value.

Token.ExpireTime

Long

The expiration time as a Unix timestamp in seconds, not a validity duration. For example, 1553825814 corresponds to 2019-03-29 02:16:54 UTC. The token is valid before this time.

The following example shows the Token field in a response.

{
  "Token": {
    "Id": "<token>",
    "ExpireTime": 1553825814
  }
}

Error response

The HTTP status code is not 200. Check the request parameters based on Code and Message.

Field

Type

Description

RequestId

String

The request ID, which can be used for troubleshooting.

Code

String

The error code.

Message

String

The error message.

For example, if the AccessKey ID does not exist, the API returns HTTP 404 with the following fields.

{
  "RequestId": "<request-id>",
  "Code": "InvalidAccessKeyId.NotFound",
  "Message": "Specified access key is not found."
}

Related topics