# Cloudflare TURN Server App name on Cloudflare: **toma** ## Credentials | Field | Value | |-------|-------| | Turn Token ID | (stored locally) | | API Token | (stored locally) | ## Generating ICE Server Credentials TURN credentials are short-lived. Generate them on demand from a back-end service using the Cloudflare API: ```bash curl \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{"ttl": 86400}' \ https://rtc.live.cloudflare.com/v1/turn/keys//credentials/generate-ice-servers ``` - `ttl` is the credential lifetime in seconds (86400 = 24 hours) - The API Token goes in the `Authorization: Bearer` header - The Turn Token ID is part of the URL path ## Response The response JSON can be passed directly into `RTCPeerConnection`: ```json { "iceServers": [ { "urls": [ "stun:stun.cloudflare.com:3478", "turn:turn.cloudflare.com:3478?transport=udp", "turn:turn.cloudflare.com:3478?transport=tcp", "turns:turn.cloudflare.com:5349?transport=tcp" ], "username": "xxxx", "credential": "yyyy" } ] } ``` The `username` and `credential` values are temporary, valid for the requested `ttl` duration. ## Usage in JavaScript ```js const res = await fetch( "https://rtc.live.cloudflare.com/v1/turn/keys//credentials/generate-ice-servers", { method: "POST", headers: { "Authorization": "Bearer ", // read from .credentials/cloudflare-turn-token.txt "Content-Type": "application/json" }, body: JSON.stringify({ ttl: 86400 }) } ); const iceConfig = await res.json(); const pc = new RTCPeerConnection(iceConfig); ``` **Important:** The credential-generation request should come from a server or trusted backend, since the API Token is a secret. Do not expose the API Token in client-side code. ## Server URLs | Protocol | URL | Port | |----------|-----|------| | STUN | `stun:stun.cloudflare.com:3478` | 3478 | | TURN (UDP) | `turn:turn.cloudflare.com:3478?transport=udp` | 3478 | | TURN (TCP) | `turn:turn.cloudflare.com:3478?transport=tcp` | 3478 | | TURNS (TLS) | `turns:turn.cloudflare.com:5349?transport=tcp` | 5349 |