Concepts / Clients & rooms

Clients & rooms

Clients and rooms are optional labels you attach to a credential request. They do not change how TURN works; they let you find a call, a participant or a session later in the dashboard and connect it to your own records.

The three fields#

Field Meaning
initiator_client The participant that starts the connection, usually the one that creates the SDP offer
receiver_client The participant that answers
room The call, meeting or channel the connection belongs to

Send any combination of them in the body of POST /credentials/ice:

bash
curl -X POST https://turnix.io/api/v1/credentials/ice \
  -H "Authorization: Bearer $TURNIX_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"ttl": 3600, "room": "standup-2026-10-30", "initiator_client": "user-1842", "receiver_client": "user-77"}'
javascript
const response = await fetch("https://turnix.io/api/v1/credentials/ice", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.TURNIX_API_TOKEN}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    ttl: 3600,
    room: "standup-2026-10-30",
    initiator_client: "user-1842",
    receiver_client: "user-77",
  }),
});
python
response = requests.post(
    "https://turnix.io/api/v1/credentials/ice",
    headers={"Authorization": f"Bearer {os.environ['TURNIX_API_TOKEN']}"},
    json={
        "ttl": 3600,
        "room": "standup-2026-10-30",
        "initiator_client": "user-1842",
        "receiver_client": "user-77",
    },
    timeout=10,
)

How Turnix stores them#

  • Clients and rooms belong to a project and are identified by name.
  • The first request with a new name creates the client or room. Later requests with the same name reuse it. There is no separate "create" call.
  • When a request contains a room, the clients in that request are linked to the room. A room can hold any number of clients, and a client can be in many rooms.
  • The credential remembers its initiator, receiver and room, so every TURN session started with it can be traced back.

In the dashboard you can then open:

  • Rooms: each room with its clients
  • Clients: each client with its rooms, credentials and relayed sessions
  • Credentials: filter credentials by client
  • Sessions: TURN sessions and their traffic

Naming rules#

Values may contain only letters, digits, - and _ (^[A-Za-z0-9_-]+$). Any other character, including spaces, dots, @ and an empty string, makes the whole request fail:

json
{ "error": "room contains invalid characters", "code": "unprocessable_entity" }

So omit a field instead of sending it empty, and sanitize values before you send them, for example:

javascript
const label = (id) => String(id).replace(/[^A-Za-z0-9_-]/g, "-").slice(0, 64) || undefined;

Keep names short and stable. Very long values are not useful in the dashboard.

Do not send personal data

Everyone with access to your Turnix project can see these labels. Use internal IDs (user-1842) or opaque hashes, not email addresses or names.

Patterns#

1:1 calls. Each side requests its own credentials. Send the same room and the same initiator_client/receiver_client pair from both sides, so both credentials appear under one room with both participants.

Group calls (SFU or mesh). Send room and set initiator_client to the participant who is requesting. Leave receiver_client out. The room then lists everyone who joined.

Correlating with your system. Use the same identifiers you use in your own logs (call ID, user ID). When a user reports a bad call, you can search for the room or client in the dashboard and see which region and sessions were involved.

Last updated October 30, 2026