SDKs / Dart / Flutter

Dart / Flutter

turnix_dart wraps POST /credentials/ice and GET /regions for Dart. It returns typed objects, including the expiry time.

Package: turnix_dart on pub.dev · Source: github.com/turnixio/turnix_dart

Integrate in seconds with your AI agent

Building a Flutter app? The Flutter integration guide has a ready-made prompt for Claude Code, Cursor or Copilot that adds the backend endpoint and the app side in one go.

Use it on your server, not in the app

The SDK needs your API token. If you ship the token inside a Flutter app, anyone can extract it. Run the SDK in a Dart backend (for example with shelf or dart_frog), and let the app fetch only iceServers from that backend.

Install#

bash
dart pub add turnix_dart
dart
import 'package:turnix_dart/turnix_dart.dart';

Request credentials#

dart
import 'dart:io';
import 'package:turnix_dart/turnix_dart.dart';

final creds = await TurnixIO.getIceCredentials(
  apiToken: Platform.environment['TURNIX_API_TOKEN']!,
  ttl: 3600,
  room: 'room-42',
  initiatorClient: 'user-1842',
  clientIp: '203.0.113.42', // the end user's public IP, for geo-routing
);

print(creds.expiresAt); // DateTime (UTC)

Return the servers to your app as JSON, for example:

dart
final body = {
  'iceServers': creds.iceServers
      .map((s) => {
            'urls': s.urls,
            if (s.username != null) 'username': s.username,
            if (s.credential != null) 'credential': s.credential,
          })
      .toList(),
  'expiresAt': creds.expiresAt.toIso8601String(),
};

In the Flutter app, with flutter_webrtc:

dart
final pc = await createPeerConnection({'iceServers': json['iceServers']});

For the complete app side (fetching, refreshing before ICE restarts, verifying the relay), see the Flutter integration guide.

API#

TurnixIO.getIceCredentials(...)#

Returns Future<IceCredentials>. Only apiToken is required.

Parameter Type Sent as
apiToken String Authorization: Bearer … header
ttl int? ttl
room String? room
initiatorClient String? initiator_client
receiverClient String? receiver_client
preferredRegion String? preferred_region
fixedRegion String? fixed_region
clientIp String? X-TURN-CLIENT-IP header

IceCredentials has iceServers (List<IceServer>, each with urls, username?, credential?) and expiresAt (DateTime).

Throws http.ClientException with the status code (for example Failed to fetch ICE credentials (429)) for any non-200 response.

TurnixIO.getAvailableRegions(apiToken: ...)#

Returns Future<List<Region>> with slug, nat2 (country code), city, name, lat, lon, isOnline and isOperational.

dart
final regions = await TurnixIO.getAvailableRegions(apiToken: token);
final usable = regions.where((r) => r.isOnline && r.isOperational);

Refreshing before expiry#

dart
if (creds.expiresAt.difference(DateTime.now().toUtc()) < const Duration(seconds: 60)) {
  creds = await TurnixIO.getIceCredentials(apiToken: token, ttl: 3600);
}

See Credentials & TTL for when to refresh.

Last updated October 30, 2026