Integrations / Shared-secret credentials (LTC)

Shared-secret credentials (LTC)

Some software cannot call an API for TURN credentials. Instead, you configure a TURN host and a shared secret, and the software generates time-limited credentials itself. This is the widely used "TURN REST API" scheme from coturn (use-auth-secret). Turnix supports it with a per-project auth secret, shown in the dashboard as LTC/Auth Token.

Use it for Nextcloud Talk, Jitsi Meet, and any other app that asks for a "TURN secret". For code you write yourself, prefer the credentials API: it adds geo-routing and client/room tracking.

Get your auth secret#

  1. Open LTC/Auth Token in the dashboard (under Turn Server) for the project you want to bill.
  2. Click Create. The secret is shown on the page.
  3. Store it like a password.
Rotating replaces the secret immediately

Rotate creates a new secret and invalidates the old one at once. Every app configured with the old secret stops getting relay until you update it. Each project has one active secret.

Pick a TURN host#

Shared-secret credentials do not use geo-routing: you choose the region yourself. Open Server in the dashboard (or call GET /regions) and pick an online region close to your users. On the free plan, use a region marked as available for your plan.

Setting Value
STUN stun.turnix.io:3478
TURN host <region>.turnix.io, for example us-west.turnix.io
TURN ports 3478 for turn: over UDP and TCP, 443 for turns: (TLS over TCP)
Secret Your auth secret
Realm Not required

How the credentials are built#

The app generates them on its own, so you usually do not need to do anything. For reference, or if you build your own integration:

  • username = the expiry time as a Unix timestamp in seconds, for example 1793365200
  • credential = Base64 of HMAC-SHA1 of the username, keyed with the auth secret
javascript
import crypto from "node:crypto";

const ttl = 3600;
const username = String(Math.floor(Date.now() / 1000) + ttl);
const credential = crypto
  .createHmac("sha1", process.env.TURNIX_AUTH_SECRET)
  .update(username)
  .digest("base64");

const iceServers = [
  { urls: "stun:stun.turnix.io:3478" },
  {
    urls: [
      "turn:us-west.turnix.io:3478?transport=udp",
      "turn:us-west.turnix.io:3478?transport=tcp",
      "turns:us-west.turnix.io:443?transport=tcp",
    ],
    username,
    credential,
  },
];

The TURN server rejects credentials whose timestamp is in the past. Traffic relayed with them counts toward the project that owns the secret.

Manage the secret via the API#

You can read and rotate the secret with a project API token, for example from a deployment script:

Endpoint Description
GET /api/v1/ltc/key Returns {"key": "<secret>"}, or {} if the project has no secret yet.
POST /api/v1/ltc/rotate Creates a new secret, invalidates the previous one, and returns {"key": "<new secret>"}.
bash
curl -s https://turnix.io/api/v1/ltc/key -H "Authorization: Bearer $TURNIX_API_TOKEN"

Last updated October 30, 2026