Turnix is a managed TURN and STUN service for WebRTC. Your backend asks the Turnix API for short-lived credentials, hands them to your clients, and the clients use Turnix servers to connect, even behind strict NATs and firewalls.
Using Claude Code, Cursor or GitHub Copilot? Copy a ready-made prompt from Build with AI agents and your agent adds Turnix to your app, including the backend endpoint, error handling and tests. There are prompts for web apps, Flutter, Node.js, Nextcloud Talk, Jitsi Meet and migrating from coturn.
Prefer doing it yourself? The Quickstart gets you to ICE servers in your RTCPeerConnection in about five minutes.
Why WebRTC needs STUN and TURN#
WebRTC tries to connect peers directly. To find a working path, each peer gathers ICE candidates:
| Candidate | Comes from | Works when |
|---|---|---|
| Host | The device's own network interfaces | Both peers are on the same network |
| Server-reflexive | A STUN server that tells the peer its public IP and port | NATs on both sides allow hole punching |
| Relay | A TURN server that forwards the media | Always, as long as the peer can reach the TURN server |
STUN is cheap: it only answers "what is my public address?". TURN carries the actual media when no direct path exists, for example on corporate networks, mobile carrier NAT (CGNAT) or networks that block UDP. Without TURN, a noticeable share of calls fails to connect or has one-way audio.
You want both: STUN so most calls connect directly, TURN as the fallback that makes the rest work.
How Turnix works#
┌──────────────┐ 1. POST /api/v1/credentials/ice ┌──────────────┐
│ Your backend │ ───────────────────────────────────▶ │ Turnix API │
│ (API token) │ ◀─────────────────────────────────── │ │
└──────┬───────┘ 2. iceServers + expiresAt └──────────────┘
│ 3. iceServers (no API token)
▼
┌──────────────┐ 4. STUN / TURN (UDP, TCP, TLS) ┌──────────────┐
│ Browser / │ ───────────────────────────────────▶ │ Turnix TURN │ ◀── other peer
│ mobile app │ │ <region>.turnix.io
└──────────────┘ └──────────────┘
- Your backend calls
POST /credentials/icewith a project API token. - Turnix picks a region (nearest to the user, or the one you ask for), creates a one-time username and password, and returns a ready-to-use
iceServersarray plus anexpiresAttimestamp. - Your backend passes
iceServersto the client. The API token never leaves your server. - The client passes
iceServerstoRTCPeerConnection. The browser uses STUN atstun.turnix.ioand, when needed, relays through<region>.turnix.io.
Every credential request is recorded in your project, so you can see credentials, TURN sessions, clients, rooms and traffic in the dashboard.
Key terms#
| Term | Meaning |
|---|---|
| Organization | Your account. Billing, plan and usage limits apply per organization. |
| Project | A container for API tokens, credentials and statistics, for example one per app or environment. |
| API token | A secret bearer token that belongs to one project. Use it from server-side code only. See Authentication. |
| ICE credentials | A short-lived TURN username/password plus the STUN and TURN URLs, in WebRTC's iceServers format. See Credentials & TTL. |
| Region | A Turnix TURN location, such as us-west. See Regions & geo-routing. |
| Clients and rooms | Optional labels you attach to a credential request to trace calls in the dashboard. See Clients & rooms. |
| Auth secret (LTC) | A per-project shared secret for software that generates TURN credentials itself, such as Nextcloud Talk and Jitsi. See Shared-secret credentials. |
Where to go next#
- Build with AI agents: let your coding agent do the integration.
- Quickstart: create a token and request your first credentials.
- API reference: every endpoint, parameter and error.
- SDKs: thin wrappers for Node.js and Dart/Flutter.
- Integrations: Flutter, Nextcloud Talk and Jitsi Meet.
- Pricing: plans are based on relayed traffic. You can start for free.