{"openapi":"3.1.0","info":{"title":"Tõlk.fm Public API","version":"1.0.0","description":"Programmatically create translation events, launch live sessions, and retrieve public stream links.\n\n## Authentication\nSend your API key in the `Authorization` header:\n```\nAuthorization: Bearer sk_live_...\n```\nCreate keys in the Tõlk.fm dashboard under **Developers**.\n\n## Quick start\n1. `POST /v1/events` — create an event with target languages\n2. `POST /v1/events/{id}/launch` — go live and receive `streamUrl` and/or `directStreamLinks`\n3. Share `streamUrl` with browser listeners or use `directStreamLinks` for OBS, vMix, and custom integrations\n4. `POST /v1/events/{id}/stop` — end the session"},"servers":[{"url":"https://api.tolk.fm"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"API key (sk_live_...)"}},"schemas":{"ApiError":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"requestId":{"type":"string"}},"required":["code","message","requestId"]}}},"Channel":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"targetLanguage":{"type":"string"},"translationProvider":{"type":"string","enum":["openai","gemini"]},"status":{"type":"string"},"stageId":{"type":"string","format":"uuid","nullable":true}}},"Event":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"status":{"type":"string"},"joinCode":{"type":"string"},"customJoinSlug":{"type":"string","nullable":true},"streamUrl":{"type":"string","format":"uri"},"sourceLanguage":{"type":"string"},"translationProvider":{"type":"string"},"startedAt":{"type":"string","format":"date-time","nullable":true},"endedAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"},"channels":{"type":"array","items":{"$ref":"#/components/schemas/Channel"}}}},"CreateEventRequest":{"type":"object","required":["title"],"properties":{"title":{"type":"string","minLength":2,"maxLength":120},"description":{"type":"string","maxLength":500},"sourceLanguage":{"type":"string","default":"auto"},"translationProvider":{"type":"string","enum":["openai","gemini"],"default":"openai"},"targetLanguages":{"type":"array","items":{"type":"string"}},"captionsEnabled":{"type":"boolean","default":false}}},"LaunchRequest":{"type":"object","properties":{"mode":{"type":"string","enum":["live","test"],"default":"live"},"inputDeviceId":{"type":"string","nullable":true},"streamDelivery":{"type":"string","enum":["listener","direct","both"],"default":"listener"},"directStream":{"type":"object","properties":{"protocols":{"type":"array","items":{"type":"string","enum":["websocket-pcm16","hls-aac","rtmp"]}},"ttlSeconds":{"type":"integer","minimum":300,"maximum":86400},"languages":{"type":"array","items":{"type":"string"}}}}}},"DirectStreamLink":{"type":"object","properties":{"language":{"type":"string"},"protocol":{"type":"string","enum":["websocket-pcm16","hls-aac","rtmp"]},"url":{"type":"string","format":"uri"},"expiresAt":{"type":"string","format":"date-time"},"sampleRate":{"type":"integer"}}},"DirectStreamLinks":{"type":"object","properties":{"recommended":{"type":"string","enum":["websocket-pcm16","hls-aac","rtmp"]},"protocols":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"label":{"type":"string"},"status":{"type":"string","enum":["ready","planned"]},"usage":{"type":"string"}}}},"links":{"type":"array","items":{"$ref":"#/components/schemas/DirectStreamLink"}}}},"LaunchResponse":{"type":"object","properties":{"status":{"type":"string"},"streamUrl":{"type":"string","format":"uri"},"joinCode":{"type":"string"},"channels":{"type":"array","items":{"$ref":"#/components/schemas/Channel"}},"startedAt":{"type":"string","format":"date-time","nullable":true},"directStreamLinks":{"$ref":"#/components/schemas/DirectStreamLinks"}}}}},"paths":{"/v1/whoami":{"get":{"summary":"Introspect API key","tags":["Auth"],"responses":{"200":{"description":"Current key metadata","content":{"application/json":{"schema":{"type":"object","properties":{"organizerId":{"type":"string","format":"uuid"},"apiKeyId":{"type":"string","format":"uuid"},"keyPrefix":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/events":{"get":{"summary":"List events","tags":["Events"],"parameters":[{"name":"status","in":"query","schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer","default":50}}],"responses":{"200":{"description":"Event list","content":{"application/json":{"schema":{"type":"object","properties":{"events":{"type":"array","items":{"$ref":"#/components/schemas/Event"}}}}}}}}},"post":{"summary":"Create event","tags":["Events"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEventRequest"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}}},"422":{"description":"Validation error"}}}},"/v1/events/{eventId}":{"get":{"summary":"Get event","tags":["Events"],"parameters":[{"name":"eventId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Event","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}}},"404":{"description":"Not found"}}}},"/v1/events/{eventId}/channels":{"post":{"summary":"Add target language channel","tags":["Events"],"parameters":[{"name":"eventId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["targetLanguage"],"properties":{"targetLanguage":{"type":"string"},"translationProvider":{"type":"string","enum":["openai","gemini"]},"stageId":{"type":"string","format":"uuid"}}}}}},"responses":{"201":{"description":"Channel created"}}}},"/v1/events/{eventId}/launch":{"post":{"summary":"Launch translation session","description":"Starts live translation and returns the public stream URL for listeners.","tags":["Sessions"],"parameters":[{"name":"eventId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LaunchRequest"}}}},"responses":{"200":{"description":"Launched","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LaunchResponse"}}}},"402":{"description":"Insufficient wallet balance"},"429":{"description":"Rate limit or concurrent events limit"}}}},"/v1/events/{eventId}/stop":{"post":{"summary":"Stop translation session","tags":["Sessions"],"parameters":[{"name":"eventId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Stopped"}}}},"/v1/events/{eventId}/direct-stream-links":{"post":{"summary":"Mint direct stream links","description":"Returns tokenized WebSocket, HLS, and RTMP URLs for broadcast integrations. Event must be live.","tags":["Sessions"],"parameters":[{"name":"eventId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"protocols":{"type":"array","items":{"type":"string","enum":["websocket-pcm16","hls-aac","rtmp"]}},"ttlSeconds":{"type":"integer"},"languages":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"200":{"description":"Direct stream links","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DirectStreamLinks"}}}}}}},"/v1/events/{eventId}/status":{"get":{"summary":"Get session status and stream link","tags":["Sessions"],"parameters":[{"name":"eventId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"include","in":"query","schema":{"type":"string"},"description":"Comma-separated includes, e.g. directStreamLinks"}],"responses":{"200":{"description":"Status","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"streamUrl":{"type":"string","format":"uri"},"joinCode":{"type":"string"},"startedAt":{"type":"string","nullable":true},"endedAt":{"type":"string","nullable":true},"channels":{"type":"array","items":{"$ref":"#/components/schemas/Channel"}},"directStreamLinks":{"$ref":"#/components/schemas/DirectStreamLinks"}}}}}}}}}}}