Request ICE Credentials
POST /credentials/ice
β
Request ICE credentials for your project to establish peer-to-peer WebRTC connections via Turnix's global TURN infrastructure.
π Simple Request Exampleβ
- CURL
- Ruby
- Node.js
- Dart
- Java
curl -X POST \
https://turnix.io/api/v1/credentials/ice \
-H 'Authorization: Bearer YOUR_API_BEARER_TOKEN' \
-H 'Content-Type: application/json'
require 'httparty'
response = HTTParty.post(
"https://turnix.io/api/v1/credentials/ice",
headers: {
"Authorization" => "Bearer YOUR_API_BEARER_TOKEN"
}
)
puts response.code # HTTP status code
puts response.body # Response body
const fetch = require('node-fetch');
(async () => {
try {
const response = await fetch('https://turnix.io/api/v1/credentials/ice', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_BEARER_TOKEN',
'Content-Type': 'application/json'
}
});
if (!response.ok) {
throw new Error(`Request failed with status ${response.status}`);
}
const data = await response.json();
console.log('Response:', data);
} catch (error) {
console.error('Error:', error.message);
}
})();
import 'package:http/http.dart' as http;
final headers = <String, String>{
'Authorization': 'Bearer $apiToken',
'Accept': 'application/json',
'Content-Type': 'application/json',
};
final response = await http.post(
Uri.parse("https://turnix.io/api/v1/credentials/ice"),
headers: headers
);
final body = json.decode(response.body) as Map<String, dynamic>;
import java.net.http.*;
import java.net.URI;
HttpClient client = HttpClient.newHttpClient();
String apiToken = "YOUR_API_TOKEN";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://turnix.io/api/v1/credentials/ice"))
.header("Authorization", "Bearer " + apiToken)
.header("Accept", "application/json")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
Response
{
"iceServers": [
{
"urls": [
"stun:stun.turnix.io:3478"
]
},
{
"username": "35bb4eb4-b518-4059-9399-272efdefc5d9",
"credential": "7ea616da55d417f4aaf6427016140416",
"urls": [
"turn:some-region.tunix.io:3478?transport=udp",
"turn:some-region.tunix.io:3478?transport=tcp"
]
}
]
}
π Parametersβ
Parameter | Type | Description |
---|---|---|
initiator_client | Optional | Identifier for the initiating client. |
receiver_client | Optional | Identifier for the receiving client. |
room | Optional | Room/session name used for grouping connections. |
ttl | Optional | Time-to-live in seconds for credentials. Default: 30 seconds. |
fixed_region | Optional | Force allocation in a specific region. Fails if the region is unavailable. |
preferred_region | Optional | Preferred region for TURN relay. Falls back to nearest available region if unavailable. |
π§Ύ Headersβ
Header | Type | Description |
---|---|---|
Authorization | Required | Bearer YOUR_API_TOKEN β used to authenticate the request. |
X-TURN-CLIENT-IP | Optional | IP address of the client (used for geo-based region routing). |
π GeoIP-Based Region Selectionβ
Turnix automatically selects the nearest TURN server using GeoIP, based on the clientβs IP address. If your server is making the request on behalf of the client (which is recommended to avoid exposing API tokens), you can forward the clientβs IP manually.
β€ Region Selectionβ
Use region parameters to influence TURN server location:
- CURL
- Ruby
- Node.js
- Dart
- Java
curl -X POST \
https://turnix.io/api/v1/credentials/ice \
-H 'Authorization: Bearer YOUR_API_BEARER_TOKEN' \
-d 'preffered_region=eu-central'
curl -X POST \
https://turnix.io/api/v1/credentials/ice \
-H 'Authorization: Bearer YOUR_API_BEARER_TOKEN' \
-d 'fixed_region=eu-central'
require 'httparty'
url = 'https://example.com/credentials/ice'
bearer_token = 'YOUR_BEARER_TOKEN'
response = HTTParty.post(url, {
headers: {
'Authorization' => "Bearer #{bearer_token}",
'Content-Type' => 'application/json'
},
body: {
preffered_region: 'eu-central',
# fixed_region: 'eu-central', # use one of both
}
})
puts response.body
const fetch = require('node-fetch'); // Only if you're using Node.js
const url = 'https://example.com/credentials/ice';
const bearerToken = 'YOUR_BEARER_TOKEN';
fetch(url, {
method: 'POST',
headers: {
'Authorization': `Bearer ${bearerToken}`,
'Content-Type': 'application/json'
},
body: new URLSearchParams({
fixed_region: 'eu-central',
// preffered_region: 'eu-central' // use one of both
})
})
.then(response => {
...
})
import 'package:http/http.dart' as http;
import 'dart:convert';
final apiToken = 'YOUR_API_TOKEN';
final response = await http.post(
Uri.parse('https://turnix.io/api/v1/credentials/ice'),
headers: {
'Authorization': 'Bearer $apiToken',
'Content-Type': 'application/json',
},
body: json.encode({
'preferred_region': 'eu-central',
// 'fixed_region': 'eu-central', // use one of both
}),
);
final body = json.decode(response.body);
print(body);
import java.net.URI;
import java.net.http.*;
import java.time.Duration;
HttpClient client = HttpClient.newHttpClient();
String apiToken = "YOUR_API_TOKEN";
JSONObject body = new JSONObject().put("preferred_region", "singapore");
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://turnix.io/api/v1/credentials/ice"))
.header("Authorization", "Bearer " + apiToken)
.header("Accept", "application/json")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(body.toString()))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
Response
{
"iceServers": [
{
"urls": [
"stun:stun.turnix.io:3478"
]
},
{
"username": "35bb4eb4-b518-4059-9399-272efdefc5d9",
"credential": "7ea616da55d417f4aaf6427016140416",
"urls": [
"turn:some-region.tunix.io:3478?transport=udp",
"turn:some-region.tunix.io:3478?transport=tcp"
]
}
]
}
β€ Forwarding Client IPβ
Forward the original clientβs IP address in the X-TURN-CLIENT-IP
header:
- CURL
- Ruby
- Node.js
- Dart
- Java
curl -X POST \
https://turnix.io/api/v1/credentials/ice \
-H 'Authorization: Bearer YOUR_API_BEARER_TOKEN' \
-H 'X-TURN-CLIENT-IP: 12.34.56.78' \
require 'httparty'
url = 'https://example.com/credentials/ice'
bearer_token = 'YOUR_BEARER_TOKEN'
response = HTTParty.post(url, {
headers: {
'Authorization' => "Bearer #{bearer_token}",
'Content-Type' => 'application/json'
'X-TURN-CLIENT-IP' => '12.34.56.78'
}
})
puts response.body
const fetch = require('node-fetch'); // Only if you're using Node.js
const url = 'https://example.com/credentials/ice';
const bearerToken = 'YOUR_BEARER_TOKEN';
fetch(url, {
method: 'POST',
headers: {
'Authorization': `Bearer ${bearerToken}`,
'Content-Type': 'application/json'
'X-TURN-CLIENT-IP': '12.34.56.78'
}
})
.then(response => {
...
})
import 'package:http/http.dart' as http;
import 'dart:convert';
final apiToken = 'YOUR_API_TOKEN';
final clientIp = '12.34.56.78';
final response = await http.post(
Uri.parse('https://turnix.io/api/v1/credentials/ice'),
headers: {
'Authorization': 'Bearer $apiToken',
'Content-Type': 'application/json',
'X-TURN-CLIENT-IP': clientIp,
},
);
final body = json.decode(response.body);
print(body);
import java.net.URI;
import java.net.http.*;
import java.time.Duration;
HttpClient client = HttpClient.newHttpClient();
String apiToken = "YOUR_API_TOKEN";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://turnix.io/api/v1/credentials/ice"))
.header("Authorization", "Bearer " + apiToken)
.header("Content-Type", "application/json")
.header("X-TURN-CLIENT-IP", "12.34.56.78")
.POST(HttpRequest.BodyPublishers.noBody())
.timeout(Duration.ofSeconds(10))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
Response
{
"iceServers": [
{
"urls": [
"stun:stun.turnix.io:3478"
]
},
{
"username": "35bb4eb4-b518-4059-9399-272efdefc5d9",
"credential": "7ea616da55d417f4aaf6427016140416",
"urls": [
"turn:some-region.tunix.io:3478?transport=udp",
"turn:some-region.tunix.io:3478?transport=tcp"
]
}
]
}
π₯ Clients and Room Contextβ
Specifying initiator_client
, receiver_client
, and room
improves observability and lets you trace interactions in the Turnix Console.
- Initiator Client: the endpoint initiating the WebRTC connection
- Receiver Client: the endpoint that receives the connection
- Room: an optional grouping for multiple clients (useful for multiparty or tracking)
This metadata is visible in the Turnix Console and can be linked back to your system.
- CURL
- Ruby
- Node.js
- Dart
- Java
curl -X POST \
https://turnix.io/api/v1/credentials/ice \
-H 'Authorization: Bearer YOUR_API_BEARER_TOKEN' \
-d 'initiator_client=OPTIONAL_INITIATOR_CLIENT_VALUE' \
-d 'receiver_client=OPTIONAL_RECEIVER_CLIENT_VALUE' \
-d 'room=OPTIONAL_ROOM_NAME_VALUE'
require 'httparty'
response = HTTParty.post(
"https://turnix.io/api/v1/credentials/ice",
headers: {
"Authorization" => "Bearer YOUR_API_BEARER_TOKEN"
},
body: {
initiator_client: "OPTIONAL_INITIATOR_CLIENT_VALUE",
receiver_client: "OPTIONAL_RECEIVER_CLIENT_VALUE",
room: "OPTIONAL_TEAM_NAME_VALUE"
}
)
puts response.code # HTTP status code
puts response.body # Response body
const fetch = require('node-fetch');
(async () => {
try {
const response = await fetch('https://turnix.io/api/v1/credentials/ice', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_BEARER_TOKEN',
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams({
initiator_client: 'OPTIONAL_INITIATOR_CLIENT_VALUE',
receiver_client: 'OPTIONAL_RECEIVER_CLIENT_VALUE',
room: 'OPTIONAL_TEAM_NAME_VALUE'
})
});
if (!response.ok) {
throw new Error(`Request failed with status ${response.status}`);
}
const data = await response.json();
console.log('Response:', data);
} catch (error) {
console.error('Error:', error.message);
}
})();
import 'package:http/http.dart' as http;
import 'dart:convert';
final apiToken = 'YOUR_API_TOKEN';
final response = await http.post(
Uri.parse('https://turnix.io/api/v1/credentials/ice'),
headers: {
'Authorization': 'Bearer $apiToken',
'Content-Type': 'application/json',
},
body: json.encode({
'initiator_client': 'OPTIONAL_INITIATOR_CLIENT_VALUE',
'receiver_client': 'OPTIONAL_RECEIVER_CLIENT_VALUE',
'room': 'OPTIONAL_ROOM_NAME_VALUE',
}),
);
final body = json.decode(response.body);
print(body);
import java.net.URI;
import java.net.http.*;
import java.time.Duration;
HttpClient client = HttpClient.newHttpClient();
String apiToken = "YOUR_API_TOKEN";
JSONObject body = new JSONObject()
.put("initiator_client", "OPTIONAL_INITIATOR_CLIENT_VALUE")
.put("receiver_client", "OPTIONAL_RECEIVER_CLIENT_VALUE")
.put("room", "OPTIONAL_ROOM_VALUE");
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://turnix.io/api/v1/credentials/ice"))
.header("Authorization", "Bearer " + apiToken)
.header("Accept", "application/json")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(body.toString()))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
Response
{
"iceServers": [
{
"urls": [
"stun:stun.turnix.io:3478"
]
},
{
"username": "35bb4eb4-b518-4059-9399-272efdefc5d9",
"credential": "7ea616da55d417f4aaf6427016140416",
"urls": [
"turn:some-region.tunix.io:3478?transport=udp",
"turn:some-region.tunix.io:3478?transport=tcp"
]
}
]
}