# 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](https://turnix.io/docs/integrations/nextcloud), [Jitsi Meet](https://turnix.io/docs/integrations/jitsi), and any other app that asks for a "TURN secret". For code you write yourself, prefer the [credentials API](https://turnix.io/docs/api-reference/credentials): it adds geo-routing and client/room tracking.

## Get your auth secret

1. Open [LTC/Auth Token](https://turnix.io/app/turn/ltc) 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.

> **Warning: 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](https://turnix.io/app/turn/server) in the dashboard (or call [`GET /regions`](https://turnix.io/docs/api-reference/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](https://turnix.io/docs/api-reference/authentication), 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"
```
