RESTful authentication
Updated
Set up RESTful authentication for Conversational AI Platform REST API requests.
Preview documentation
Conversational AI Platform REST API requests require authentication. Use one of the following methods:
- Token authentication: Generate a token with your App ID and App Certificate, and set
Authorization: agora token="<your_token>". - Basic HTTP authentication: Generate a Base64-encoded credential from your customer ID and customer secret, and set
Authorization: Basic <base64_credentials>.
Implement authentication on the server to mitigate the risk of data leakage.
Choose an authentication method
You can use either method for any Platform API request. Choose the one recommended for your use case:
| Use case | Recommended method | Why |
|---|---|---|
| Telephony only: inbound calls, outbound calls, and campaigns, with no RTC channel | Basic HTTP authentication | You authenticate with your customer ID and customer secret. You don't need to generate tokens. |
| RTC, or RTC and telephony | Token authentication | An RTC session needs a token for the agent to join the channel. You can use the same token to authenticate your requests. |
Token authentication
Token authentication uses a token generated on your server with your App ID and App Certificate. To authenticate with a token, include the Authorization header in each request:
Authorization: agora token="<your_token>"Prerequisites
Before you begin, get the following values from Agora Console:
- App ID: A unique string that identifies your project.
- App Certificate: A string used to generate tokens.
Never expose your App Certificate in client-side code or public repositories. Generate tokens on your server only, and don't write tokens to public logs.
Tokens expire after a maximum of 86400 seconds.
Choose the token services
The services a token needs depend on the request:
- Requests that start an RTC session: Use a token with the ConvoAI, RTC, and RTM services, such as one from
ConvoAITokenBuilder.buildToken. Put the same token in theAuthorizationheader and intransport.token, which lets the agent join the channel. This applies when you start a session or start an ephemeral session with an RTC transport, and when you renew the token with Update a session. - All other requests: A token with only the ConvoAI service is enough. These include managing agents, secrets, phone numbers, and campaigns; listing, retrieving, and stopping sessions; and starting telephony sessions. See Build a token with specific services.
To start an RTC session, you can also generate a separate token for each place. Put the REST authentication token in the Authorization header and a token with the RTC service in transport.token.
When the token includes the RTC service, the token parameters must match the session request:
channelNamemust matchtransport.channel.- The account or UID must match
transport.uid.
Use a temporary token for testing
For testing, you can generate a temporary token in Agora Console. A temporary token is valid for 24 hours. For details, see Credentials. When you start an RTC session, use the channel name you entered when you generated the token as transport.channel in your request.
In production, generate tokens on your server using the token builder library.
Using the token builder library
The AgoraDynamicKey repository provides open-source token generation libraries for multiple languages, including ConvoAITokenBuilder and the ConvoAI service.
Install the token builder library for your language:
npm install agora-token# Pins the latest commit on the feature/access-token2-convoai-stt-services branch
go get github.com/AgoraIO/Tools/DynamicKey/AgoraDynamicKey/go/src@v0.0.0-20261010073935-b75635c32d30git clone --branch feature/access-token2-convoai-stt-services https://github.com/AgoraIO/Tools.git
cd Tools/DynamicKey/AgoraDynamicKey/python3Build a ConvoAI token
ConvoAITokenBuilder.buildToken generates a token with the ConvoAI, RTC, and RTM services. Use it to start an RTC session, with the same token in the Authorization header and in transport.token:
const { ConvoAITokenBuilder } = require('agora-token');
const appId = '<your_app_id>';
const appCertificate = '<your_app_certificate>';
const channelName = '<your_channel_name>';
const agentUid = '<your_agent_uid>';
const tokenExpire = 86400; // Token lifetime, 24 hours, in seconds
const privilegeExpire = 3600; // RTC and RTM privilege lifetime, 1 hour, in seconds
const token = ConvoAITokenBuilder.buildToken(
appId,
appCertificate,
channelName,
agentUid,
tokenExpire,
privilegeExpire,
);package main
import (
"fmt"
"log"
"github.com/AgoraIO/Tools/DynamicKey/AgoraDynamicKey/go/src/convoaitokenbuilder"
)
func main() {
appID := "<your_app_id>"
appCertificate := "<your_app_certificate>"
channelName := "<your_channel_name>"
agentUID := "<your_agent_uid>"
tokenExpire := uint32(24 * 60 * 60) // Token lifetime, 24 hours, in seconds
privilegeExpire := uint32(60 * 60) // RTC and RTM privilege lifetime, 1 hour, in seconds
token, err := convoaitokenbuilder.BuildToken(
appID,
appCertificate,
channelName,
agentUID,
tokenExpire,
privilegeExpire,
)
if err != nil {
log.Fatal(err)
}
fmt.Println(token)
}To run the example, save it as main.go in an empty folder, and run the following commands:
go mod init example.com/convoai-token-generator
go get github.com/AgoraIO/Tools/DynamicKey/AgoraDynamicKey/go/src@v0.0.0-20261010073935-b75635c32d30
go run main.goThe program prints a token that starts with 007.
from src.convoai_token_builder import ConvoAITokenBuilder
token_expire = 86400 # Token lifetime, 24 hours, in seconds
privilege_expire = 3600 # RTC and RTM privilege lifetime, 1 hour, in seconds
token = ConvoAITokenBuilder.build_token(
app_id, app_certificate, channel_name, agent_uid, token_expire, privilege_expire
)The privilege lifetime must not exceed the token lifetime. To set the RTC role or each RTC and RTM privilege separately, use buildTokenWithPrivilege (BuildTokenWithPrivilege in Go, build_token_with_privilege in Python). It also adds the ConvoAI service automatically.
Build a token with specific services
To control exactly which services a token includes, build it with the AccessToken2 API. The following examples build a token with the ConvoAI service only. Use this token in the Authorization header for requests that don't join an RTC channel:
const { AccessToken2, ServiceConvoAI } = require('agora-token/src/AccessToken2');
const tokenExpire = 86400; // Token lifetime, 24 hours, in seconds
const accessToken = new AccessToken2(appId, appCertificate, null, tokenExpire);
accessToken.add_service(new ServiceConvoAI());
const token = accessToken.build();import accesstoken "github.com/AgoraIO/Tools/DynamicKey/AgoraDynamicKey/go/src/accesstoken2"
const tokenExpire = 24 * 60 * 60 // Token lifetime, 24 hours, in seconds
accessToken := accesstoken.NewAccessToken(appID, appCertificate, tokenExpire)
accessToken.AddService(accesstoken.NewServiceConvoAI())
token, err := accessToken.Build()from src.AccessToken2 import AccessToken, ServiceConvoAI
token_expire = 86400 # Token lifetime, 24 hours, in seconds
access_token = AccessToken(app_id, app_certificate, expire=token_expire)
access_token.add_service(ServiceConvoAI())
token = access_token.build()To set the RTC privileges yourself, add the RTC service. The following examples build a token with the ConvoAI and RTC services, which works in the Authorization header and in transport.token. Each RTC privilege lifetime must not exceed the token lifetime:
const { AccessToken2, ServiceConvoAI, ServiceRtc } = require('agora-token/src/AccessToken2');
const tokenExpire = 86400; // Token lifetime, 24 hours, in seconds
const privilegeExpire = 3600; // RTC privilege lifetime, 1 hour, in seconds
const accessToken = new AccessToken2(appId, appCertificate, null, tokenExpire);
const rtc = new ServiceRtc(channelName, agentUid);
rtc.add_privilege(ServiceRtc.kPrivilegeJoinChannel, privilegeExpire);
rtc.add_privilege(ServiceRtc.kPrivilegePublishAudioStream, privilegeExpire);
rtc.add_privilege(ServiceRtc.kPrivilegePublishVideoStream, privilegeExpire);
rtc.add_privilege(ServiceRtc.kPrivilegePublishDataStream, privilegeExpire);
accessToken.add_service(rtc);
accessToken.add_service(new ServiceConvoAI());
const token = accessToken.build();import accesstoken "github.com/AgoraIO/Tools/DynamicKey/AgoraDynamicKey/go/src/accesstoken2"
const tokenExpire = 24 * 60 * 60 // Token lifetime, 24 hours, in seconds
const privilegeExpire = 60 * 60 // RTC privilege lifetime, 1 hour, in seconds
accessToken := accesstoken.NewAccessToken(appID, appCertificate, tokenExpire)
rtc := accesstoken.NewServiceRtc(channelName, agentUID)
rtc.AddPrivilege(accesstoken.PrivilegeJoinChannel, privilegeExpire)
rtc.AddPrivilege(accesstoken.PrivilegePublishAudioStream, privilegeExpire)
rtc.AddPrivilege(accesstoken.PrivilegePublishVideoStream, privilegeExpire)
rtc.AddPrivilege(accesstoken.PrivilegePublishDataStream, privilegeExpire)
accessToken.AddService(rtc)
accessToken.AddService(accesstoken.NewServiceConvoAI())
token, err := accessToken.Build()from src.AccessToken2 import AccessToken, ServiceConvoAI, ServiceRtc
token_expire = 86400 # Token lifetime, 24 hours, in seconds
privilege_expire = 3600 # RTC privilege lifetime, 1 hour, in seconds
access_token = AccessToken(app_id, app_certificate, expire=token_expire)
rtc = ServiceRtc(channel_name, agent_uid)
rtc.add_privilege(ServiceRtc.kPrivilegeJoinChannel, privilege_expire)
rtc.add_privilege(ServiceRtc.kPrivilegePublishAudioStream, privilege_expire)
rtc.add_privilege(ServiceRtc.kPrivilegePublishVideoStream, privilege_expire)
rtc.add_privilege(ServiceRtc.kPrivilegePublishDataStream, privilege_expire)
access_token.add_service(rtc)
access_token.add_service(ServiceConvoAI())
token = access_token.build()Send a request with a token
The following example lists the agents in your project. It works with a token that has only the ConvoAI service, because it doesn't join an RTC channel:
curl --request GET \
--url 'https://preview.ai.agora.io/conversational-ai/v1/projects/<your_app_id>/agents?limit=20' \
--header 'Authorization: agora token="<your_token>"'The following example starts an RTC session with a saved agent, using a token with the ConvoAI, RTC, and RTM services, such as one from ConvoAITokenBuilder.buildToken. It uses the same token in the Authorization header and in transport.token:
curl --request POST \
--url https://preview.ai.agora.io/conversational-ai/v1/projects/<your_app_id>/sessions \
--header 'Authorization: agora token="<your_token>"' \
--header 'Content-Type: application/json' \
--data '{
"agent_id": "<your_agent_id>",
"transport": {
"type": "rtc",
"channel": "<your_channel_name>",
"token": "<your_token>",
"uid": "1001",
"subscribe_uids": ["1002"]
},
"lifecycle": {
"idle_timeout_ms": 120000
}
}'The token must be generated for <your_channel_name> and UID 1001. To create an agent first, see Create an agent.
Basic HTTP authentication
Basic HTTP authentication uses your Agora customer ID and customer secret. Generate a Base64-encoded credential from the customer_id:customer_secret string, then include it in the Authorization header:
Authorization: Basic <base64_credentials>Generate Customer ID and Customer Secret
To generate a Customer ID and Customer Secret, do the following:
-
In Agora Console, click the username at the bottom of the navigation sidebar to open the account menu, then select RESTful API Keys.
-
Select Create API Key. A Customer ID and Customer Secret are generated.
-
Select Download and save the file somewhere secure — you can download it only once. In the file, Key is your Customer ID and Secret is your Customer Secret.
-
Use the Customer ID (Key) and Customer Secret (Secret) to generate a Base64-encoded credential, and pass it to the
Authorizationparameter in the HTTP request header.
Generate an authorization header using a third-party tool
For testing and debugging, you can use a third-party online tool to quickly generate your Authorization header. Enter your Customer ID as the Username and your Customer Secret as the Password. Your generated header should look like this:
Authorization: Basic NDI1OTQ3N2I4MzYy...YwZjA=Generate an authorization header using code
The following examples read your customer ID and customer secret from the AGORA_CUSTOMER_KEY and AGORA_CUSTOMER_SECRET environment variables, and print the value to use in the Authorization header:
import java.nio.charset.StandardCharsets;
import java.util.Base64;
public class BasicAuthHeader {
public static void main(String[] args) {
// Read your customer ID and customer secret from environment variables
String customerKey = System.getenv("AGORA_CUSTOMER_KEY");
String customerSecret = System.getenv("AGORA_CUSTOMER_SECRET");
// Join the customer ID and customer secret, then encode them with Base64
String plainCredentials = customerKey + ":" + customerSecret;
String base64Credentials = Base64.getEncoder()
.encodeToString(plainCredentials.getBytes(StandardCharsets.UTF_8));
// Create the Authorization header value
String authorizationHeader = "Basic " + base64Credentials;
System.out.println(authorizationHeader);
}
}package main
import (
"encoding/base64"
"fmt"
"os"
)
func main() {
// Read your customer ID and customer secret from environment variables
customerKey := os.Getenv("AGORA_CUSTOMER_KEY")
customerSecret := os.Getenv("AGORA_CUSTOMER_SECRET")
// Join the customer ID and customer secret, then encode them with Base64
plainCredentials := customerKey + ":" + customerSecret
base64Credentials := base64.StdEncoding.EncodeToString([]byte(plainCredentials))
// Create the Authorization header value
authorizationHeader := "Basic " + base64Credentials
fmt.Println(authorizationHeader)
}<?php
// Read your customer ID and customer secret from environment variables
$customerKey = getenv("AGORA_CUSTOMER_KEY");
$customerSecret = getenv("AGORA_CUSTOMER_SECRET");
// Join the customer ID and customer secret, then encode them with Base64
$plainCredentials = $customerKey . ":" . $customerSecret;
$base64Credentials = base64_encode($plainCredentials);
// Create the Authorization header value
$authorizationHeader = "Basic " . $base64Credentials;
echo $authorizationHeader . PHP_EOL;using System;
using System.Text;
public class BasicAuthHeader
{
public static void Main()
{
// Read your customer ID and customer secret from environment variables
string customerKey = Environment.GetEnvironmentVariable("AGORA_CUSTOMER_KEY");
string customerSecret = Environment.GetEnvironmentVariable("AGORA_CUSTOMER_SECRET");
// Join the customer ID and customer secret, then encode them with Base64
string plainCredentials = customerKey + ":" + customerSecret;
string base64Credentials = Convert.ToBase64String(Encoding.UTF8.GetBytes(plainCredentials));
// Create the Authorization header value
string authorizationHeader = "Basic " + base64Credentials;
Console.WriteLine(authorizationHeader);
}
}'use strict';
// Read your customer ID and customer secret from environment variables
const customerKey = process.env.AGORA_CUSTOMER_KEY;
const customerSecret = process.env.AGORA_CUSTOMER_SECRET;
// Join the customer ID and customer secret, then encode them with Base64
const plainCredentials = customerKey + ':' + customerSecret;
const base64Credentials = Buffer.from(plainCredentials).toString('base64');
// Create the Authorization header value
const authorizationHeader = 'Basic ' + base64Credentials;
console.log(authorizationHeader);import base64
import os
# Read your customer ID and customer secret from environment variables
customer_key = os.environ["AGORA_CUSTOMER_KEY"]
customer_secret = os.environ["AGORA_CUSTOMER_SECRET"]
# Join the customer ID and customer secret, then encode them with Base64
plain_credentials = customer_key + ":" + customer_secret
base64_credentials = base64.b64encode(plain_credentials.encode("utf-8")).decode("utf-8")
# Create the Authorization header value
authorization_header = "Basic " + base64_credentials
print(authorization_header)