Skip to main content
Quick Start

Token authentication

Learn how the Realtime API authenticates connections with tokens, including how to get an API key and how to authenticate over the WebSocket, WebRTC, and AOQ protocols

Learn how the Realtime API authenticates connections with tokens, including how to get an API key and how to authenticate over the WebSocket, WebRTC, and AOQ protocols. The Realtime API uses API keys for authentication. Whether you connect over AOQ, WebRTC, or WebSocket, you pass a bearer token in the Authorization HTTP request header. Authentication happens only during connection setup. After the connection is established, data transmission doesn't require re-authentication. The following table compares how the three protocols authenticate:
ProtocolWhen authentication happensAuthentication methodNotes
AOQWhen the business AppServer requests the gatewayHTTP header Authorization: Bearer $DASHSCOPE_API_KEYThe API key is used only on the server side. The client uses the token returned by the gateway
WebRTCDuring the SDP exchange HTTP requestHTTP header Authorization: Bearer $DASHSCOPE_API_KEYThe client or server initiates the SDP exchange with the API key
WebSocketDuring the WebSocket handshakeHTTP header Authorization: Bearer $DASHSCOPE_API_KEYThe client or server connects directly with the API key

Get an API key

Step 1: Activate QwenCloud

  1. Go to the QwenCloud console and log on with your account.
  2. If this is your first time using the service, follow the on-screen instructions to activate it.

Step 2: Create an API key

  1. In the left navigation pane of the console, choose API Key.
  2. Click Create API Key and select the workspace to associate with the key.
  3. After the key is created, copy and store it immediately.
Security note: The API key is your only credential for accessing the service. Don't hard-code it in client code or commit it to a code repository. Manage it through environment variables or distribute it from a backend service.

Connection authentication details

AOQ protocol authentication

AOQ uses a server-side proxy authentication model: the API key is used only on the business AppServer. The client connects with a temporary token returned by the gateway, which keeps the API key off the client.
Token authentication
  • Realtime protocol
  • Inference protocol
curl -X POST \
  "https://{endpoint}/api/v1/webrtc/realtime?model=qwen3.5-omni-plus-realtime" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DASHSCOPE_API_KEY" \
  -H "x-dashscope-rtc-transport: moq" \
  -d "{\"clientIp\": \"${CLIENT_REAL_IP}\"}"

Request fields

ItemValueDescription
endpointSelect an access domain based on your business scenarioSpecifies the access domain
Content-Typeapplication/jsonSpecifies the message type
AuthorizationBearer $DASHSCOPE_API_KEYYour API key
x-dashscope-rtc-transportmoqSpecifies the AOQ protocol
clientIpThe client's real public IP addressOptional. If not specified, the IP address that requests the QwenCloud gateway is used. If specified, the clientIp value takes precedence. The Realtime API assigns the best Relay access point based on the client IP address

Response example

{
  "sid": "1d06b55683db49bba67a407902f62d02:1782706970:69aecdc5...",
  "aoqTokenForClient": "ecc1a46015d5496ca4ff7a48281eb739",
  "clientRelayEndpoints": [{"endpoint": "121.199.XX.XX", "port": 8443, "route_index": 0}],
  "clientRelayCertFingerprint": "sha256/99843495...",
  "sidExpiresInSecs": 7200,
  "extraInfo": {"workspaceIdHash": "2021b6f98cea4cff"}
}

Response fields

FieldDescription
sidUnique session ID
aoqTokenForClientClient connection token. Pass it to the SDK's token field
clientRelayEndpointsArray of Relay access points (endpoint + port)
clientRelayCertFingerprintRelay TLS certificate fingerprint
sidExpiresInSecsSession expiration time, in seconds
extraInfo.workspaceIdHashWorkspace ID hash

AOQ Client SDK connection example

clientIp is an optional field in the request body. If not specified, the IP address that requests the QwenCloud gateway is used as the client IP. If specified, the clientIp value takes precedence. Have your business AppServer obtain the client's real IP address and pass it in to get the best Relay access point.
  • iOS (Swift)
  • Android (Java)
  • OHOS (ArkTS)
let resp = try JSONDecoder().decode(AllocateResponse.self, from: responseData)
let config = AoqConnectConfig()
config.token = resp.aoqTokenForClient
config.sid = resp.sid
config.certFingerprint = resp.clientRelayCertFingerprint
config.relayEndpoints = resp.clientRelayEndpoints.enumerated().map { index, item in
  let ep = AoqRelayEndpoint()
  // Fall back to the array index when route_index is missing
  ep.routeIndex = item.routeIndex ?? index
  ep.endpoint = item.endpoint
  ep.port = item.port
  return ep
}
config.workspaceIdHash = resp.extraInfo?.workspaceIdHash ?? ""
let audioTrack = AoqTrackParam()
audioTrack.trackType = .audio
let dataTrack = AoqTrackParam()
dataTrack.trackType = .data
config.publishTracks = [audioTrack, dataTrack]
config.subscribeTracks = [audioTrack, dataTrack]
engine.connect(config)

WebRTC protocol authentication

WebRTC completes the SDP exchange over an HTTP POST request, and authentication happens at this stage. The client sends the Offer SDP to the server, and the server returns the Answer SDP.
ItemValueDescription
Request methodPOST-
Request URLhttps://{endpoint}/api/v1/webrtc/realtime?model={model_name}Replace endpoint and model_name. The connection URL varies by model. For details, see WebRTC connection
Content-Typeapplication/sdpThe request body is an SDP string
AuthorizationBearer $DASHSCOPE_API_KEYYour API key
ResponseHTTP 200 with the Answer SDPReturns a 4xx status code on failure
const pc = new RTCPeerConnection();
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
stream.getAudioTracks().forEach(t => pc.addTrack(t, stream));
pc.createDataChannel('oai-events');
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
// Send after ICE gathering is complete
const resp = await fetch(API_URL, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/sdp',
    'Authorization': `Bearer ${API_KEY}`,
  },
  body: pc.localDescription.sdp,
});
const answerSdp = await resp.text();
await pc.setRemoteDescription({ type: 'answer', sdp: answerSdp });

WebSocket protocol authentication

WebSocket has the simplest authentication: send the API key in an HTTP header when you establish the connection.
ItemValueDescription
Connection URLwss://dashscope-intl.aliyuncs.com/api-ws/v1/realtime?model={model_name}The connection URL varies by model. For details, see WebSocket connection
AuthorizationBearer $DASHSCOPE_API_KEYYour API key
import websocket, os
API_KEY = os.getenv("DASHSCOPE_API_KEY")
URL = "wss://dashscope-intl.aliyuncs.com/api-ws/v1/realtime?model=qwen3.5-omni-plus-realtime"
ws = websocket.WebSocketApp(URL, header=["Authorization: Bearer " + API_KEY])
ws.run_forever()
Token authentication - QwenCloud