Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Comprehensive Cloudflare platform skill covering Workers, D1, R2, KV, AI, Durable Objects, and security.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
references/turn/api.md
1# TURN API Reference23Complete API documentation for Cloudflare TURN service credentials and key management.45## Authentication67All endpoints require Cloudflare API token with "Calls Write" permission.89Base URL: `https://api.cloudflare.com/client/v4`1011## TURN Key Management1213### List TURN Keys1415```16GET /accounts/{account_id}/calls/turn_keys17```1819### Get TURN Key Details2021```22GET /accounts/{account_id}/calls/turn_keys/{key_id}23```2425### Create TURN Key2627```28POST /accounts/{account_id}/calls/turn_keys29Content-Type: application/json3031{32"name": "my-turn-key"33}34```3536**Response includes**:37- `uid`: Key identifier38- `key`: The actual secret key (only returned on creation—save immediately)39- `name`: Human-readable name40- `created`: ISO 8601 timestamp41- `modified`: ISO 8601 timestamp4243### Update TURN Key4445```46PUT /accounts/{account_id}/calls/turn_keys/{key_id}47Content-Type: application/json4849{50"name": "updated-name"51}52```5354### Delete TURN Key5556```57DELETE /accounts/{account_id}/calls/turn_keys/{key_id}58```5960## Generate Temporary Credentials6162```63POST https://rtc.live.cloudflare.com/v1/turn/keys/{key_id}/credentials/generate64Authorization: Bearer {key_secret}65Content-Type: application/json6667{68"ttl": 8640069}70```7172### Credential Constraints7374| Parameter | Min | Max | Default | Notes |75|-----------|-----|-----|---------|-------|76| ttl | 1 | 172800 (48hrs) | varies | API rejects values >172800 |7778**CRITICAL**: Maximum TTL is 48 hours (172800 seconds). API will reject requests exceeding this limit.7980### Response Schema8182```json83{84"iceServers": {85"urls": [86"stun:stun.cloudflare.com:3478",87"turn:turn.cloudflare.com:3478?transport=udp",88"turn:turn.cloudflare.com:3478?transport=tcp",89"turn:turn.cloudflare.com:53?transport=udp",90"turn:turn.cloudflare.com:80?transport=tcp",91"turns:turn.cloudflare.com:5349?transport=tcp",92"turns:turn.cloudflare.com:443?transport=tcp"93],94"username": "1738035200:user123",95"credential": "base64encodedhmac=="96}97}98```99100**Port 53 Warning**: Filter port 53 URLs for browser clients—blocked by Chrome/Firefox. See [gotchas.md](./gotchas.md#using-port-53-in-browsers).101102## Revoke Credentials103104```105POST https://rtc.live.cloudflare.com/v1/turn/keys/{key_id}/credentials/revoke106Authorization: Bearer {key_secret}107Content-Type: application/json108109{110"username": "1738035200:user123"111}112```113114**Response**: 204 No Content115116Billing stops immediately. Active connection drops after short delay (~seconds).117118## TypeScript Types119120```typescript121interface CloudflareTURNConfig {122keyId: string;123keySecret: string;124ttl?: number; // Max 172800 (48 hours)125}126127interface TURNCredentialsRequest {128ttl?: number; // Max 172800 seconds129}130131interface TURNCredentialsResponse {132iceServers: {133urls: string[];134username: string;135credential: string;136};137}138139interface RTCIceServer {140urls: string | string[];141username?: string;142credential?: string;143credentialType?: "password";144}145146interface TURNKeyResponse {147uid: string;148key: string; // Only present on creation149name: string;150created: string;151modified: string;152}153```154155## Validation Function156157```typescript158function validateRTCIceServer(obj: unknown): obj is RTCIceServer {159if (!obj || typeof obj !== 'object') {160return false;161}162163const server = obj as Record<string, unknown>;164165if (typeof server.urls !== 'string' && !Array.isArray(server.urls)) {166return false;167}168169if (server.username && typeof server.username !== 'string') {170return false;171}172173if (server.credential && typeof server.credential !== 'string') {174return false;175}176177return true;178}179```180181## Type-Safe Credential Generation182183```typescript184async function fetchTURNServers(185config: CloudflareTURNConfig186): Promise<RTCIceServer[]> {187// Validate TTL constraint188const ttl = config.ttl ?? 3600;189if (ttl > 172800) {190throw new Error('TTL cannot exceed 172800 seconds (48 hours)');191}192193const response = await fetch(194`https://rtc.live.cloudflare.com/v1/turn/keys/${config.keyId}/credentials/generate`,195{196method: 'POST',197headers: {198'Authorization': `Bearer ${config.keySecret}`,199'Content-Type': 'application/json'200},201body: JSON.stringify({ ttl })202}203);204205if (!response.ok) {206throw new Error(`TURN credential generation failed: ${response.status}`);207}208209const data = await response.json();210211// Filter port 53 for browser clients212const filteredUrls = data.iceServers.urls.filter(213(url: string) => !url.includes(':53')214);215216const iceServers = [217{ urls: 'stun:stun.cloudflare.com:3478' },218{219urls: filteredUrls,220username: data.iceServers.username,221credential: data.iceServers.credential,222credentialType: 'password' as const223}224];225226// Validate before returning227if (!iceServers.every(validateRTCIceServer)) {228throw new Error('Invalid ICE server configuration received');229}230231return iceServers;232}233```234235## See Also236237- [configuration.md](./configuration.md) - Worker setup, environment variables238- [patterns.md](./patterns.md) - Implementation examples using these APIs239- [gotchas.md](./gotchas.md) - Security best practices, common mistakes240