{"info":{"contact":{"email":"support@jellypod.ai","name":"Jellypod Support","url":"https://www.jellypod.com/docs/api"},"description":"Programmatic access to Jellypod podcasts, episodes, hosts, sources, and voices.","license":{"name":"Proprietary"},"title":"Jellypod API","version":"1.0.0"},"openapi":"3.1.0","servers":[{"description":"Production","url":"https://api.jellypod.com"},{"description":"Local development","url":"http://localhost:3003"}],"tags":[{"description":"Service liveness checks.","name":"Health"},{"description":"Authenticated organization details.","name":"Account"},{"description":"Podcast resources.","name":"Podcasts"},{"description":"Episode resources.","name":"Episodes"},{"description":"Streaming and playback metrics for podcasts and episodes.","name":"Analytics"},{"description":"Host (speaker) resources.","name":"Hosts"},{"description":"Source documents fed to generation.","name":"Sources"},{"description":"TTS voices.","name":"Voices"}],"components":{"securitySchemes":{"bearerAuth":{"description":"API key issued from /developers/api-keys in the Jellypod studio. Send as `Authorization: Bearer <key>`.","scheme":"bearer","type":"http"}},"schemas":{"ApiIndex":{"type":"object","properties":{"authentication":{"type":"object","properties":{"documentation_url":{"type":"string","format":"uri"},"header":{"type":"string"},"keys_url":{"type":"string","format":"uri"},"type":{"type":"string","enum":["bearer"]}},"required":["documentation_url","header","keys_url","type"]},"description":{"type":"string"},"developers_url":{"type":"string","format":"uri"},"documentation_url":{"type":"string","format":"uri"},"errors":{"type":"object","properties":{"format":{"type":"string","enum":["application/problem+json"]},"specification":{"type":"string","format":"uri"}},"required":["format","specification"]},"llms_txt_url":{"type":"string","format":"uri"},"mcp":{"type":"object","properties":{"documentation_url":{"type":"string","format":"uri"},"server_card_url":{"type":"string","format":"uri"},"transport":{"type":"string","enum":["streamable-http"]},"url":{"type":"string","format":"uri"}},"required":["documentation_url","server_card_url","transport","url"]},"name":{"type":"string"},"openapi_url":{"type":"string","format":"uri"},"version":{"type":"string"}},"required":["authentication","description","developers_url","documentation_url","errors","llms_txt_url","mcp","name","openapi_url","version"],"description":"Discovery document linking the OpenAPI spec, docs, authentication, and MCP server."},"Account":{"type":"object","properties":{"data":{"type":"object","properties":{"organization_id":{"type":"string","readOnly":true},"plan":{"type":"string","readOnly":true},"credits":{"type":"object","properties":{"balance":{"type":"number","readOnly":true}},"required":["balance"]}},"required":["organization_id","plan","credits"]}},"required":["data"],"description":"Caller organization, current plan, and credit balance."},"ApiError":{"type":"object","properties":{"detail":{"type":"string","description":"Longer human-readable explanation when available."},"errors":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}},"required":["field","message"]},"description":"Per-field validation failures. Present when `type` is `validation_error`."},"request_id":{"type":"string","description":"Correlation id, also returned in the `X-Request-Id` response header. Include in support requests."},"status":{"type":"integer","description":"HTTP status code mirrored from the response."},"title":{"type":"string","description":"Short human-readable summary."},"type":{"type":"string","enum":["bad_request","validation_error","unauthorized","forbidden","not_found","conflict","method_not_allowed","unsupported_media_type","unprocessable_entity","rate_limited","bad_gateway","internal_error"],"description":"Machine-readable error class. Suitable for switch/match in client code."}},"required":["status","title","type"],"description":"RFC 9457 error envelope returned for all non-2xx responses from the Jellypod API."},"EpisodeAnalytics":{"type":"object","properties":{"as_of":{"type":"string","description":"ISO-8601 time these metrics were computed.","readOnly":true},"complete":{"type":"boolean","description":"Whether every analytics source answered in full. When false an upstream (OP3 or Mux) was degraded, so the numbers are a floor rather than a total; retry later for a complete read.","readOnly":true},"downloads":{"$ref":"#/components/schemas/EpisodeDownloads"},"episode_id":{"type":"string","readOnly":true},"video_views":{"$ref":"#/components/schemas/EpisodeVideoViews"}},"required":["as_of","complete","downloads","episode_id","video_views"],"description":"Streaming metrics for a single episode. Audio download windows are measured since publish; video view windows are rolling."},"EpisodeDownloads":{"type":"object","properties":{"first_7_days":{"type":"number","description":"Audio downloads in the first 7 days after publish."},"first_30_days":{"type":"number","description":"Audio downloads in the first 30 days after publish."},"total":{"type":"number","description":"All-time audio downloads (OP3)."}},"required":["first_7_days","first_30_days","total"]},"EpisodeVideoViews":{"type":"object","properties":{"last_7_days":{"type":"number","description":"Web video views in the last 7 days."},"last_30_days":{"type":"number","description":"Web video views in the last 30 days."},"total":{"type":"number","description":"Web video views over the last 90 days (Mux retention window)."}},"required":["last_7_days","last_30_days","total"]},"PodcastAnalytics":{"type":"object","properties":{"analytics_enabled":{"type":"boolean","description":"Whether download tracking is enabled. When false, audio metrics are 0."},"as_of":{"type":"string","description":"ISO-8601 time these metrics were computed.","readOnly":true},"complete":{"type":"boolean","description":"Whether every analytics source answered in full. When false an upstream (OP3 or Mux) was degraded, so the numbers are a floor rather than a total; retry later for a complete read.","readOnly":true},"episodes":{"type":"array","items":{"type":"object","properties":{"downloads":{"$ref":"#/components/schemas/EpisodeDownloads"},"episode_id":{"type":"string","readOnly":true},"video_views":{"$ref":"#/components/schemas/EpisodeVideoViews"}},"required":["downloads","episode_id","video_views"]}},"plays_by_app":{"type":"object","additionalProperties":{"type":"number"},"description":"Audio downloads grouped by client app (Spotify, Apple Podcasts, Overcast, ...). Show-level."},"podcast_id":{"type":"string","readOnly":true},"totals":{"type":"object","properties":{"downloads":{"type":"number","description":"All-time audio downloads (OP3)."},"last_7_days":{"type":"number","description":"Combined plays in the last 7 days."},"last_30_days":{"type":"number","description":"Combined plays in the last 30 days."},"plays":{"type":"number","description":"All-time audio downloads + web video views."},"video_views":{"type":"number","description":"Web video views (Mux, last 90 days)."}},"required":["downloads","last_7_days","last_30_days","plays","video_views"]}},"required":["analytics_enabled","as_of","complete","episodes","plays_by_app","podcast_id","totals"],"description":"Streaming metrics for a podcast: combined totals, per-app download breakdown, and per-episode metrics."},"ListEpisodesResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Episode"}}},"required":["data"],"description":"Page of episodes. Use the `Link` response header (`rel=\"next\"`) to paginate."},"Episode":{"type":"object","properties":{"audio_url":{"type":["string","null"],"readOnly":true},"created_at":{"type":"string","readOnly":true},"description":{"type":["string","null"]},"generation":{"type":["object","null"],"properties":{"completed_at":{"type":["string","null"]},"error_message":{"type":"string"},"started_at":{"type":"string"},"state":{"type":"string","enum":["generating","completed","failed"]}},"required":["completed_at","started_at","state"],"readOnly":true},"host_ids":{"type":["array","null"],"items":{"type":"string"}},"id":{"type":"string","readOnly":true},"image_url":{"type":["string","null"]},"podcast_id":{"type":"string"},"published_at":{"type":["string","null"],"readOnly":true},"scheduled_at":{"type":["string","null"],"readOnly":true},"source_ids":{"type":"array","items":{"type":"string"},"readOnly":true},"status":{"$ref":"#/components/schemas/EpisodeStatus"},"title":{"type":["string","null"]},"updated_at":{"type":"string","readOnly":true},"url":{"type":["string","null"],"readOnly":true},"video_url":{"type":["string","null"],"readOnly":true}},"required":["audio_url","created_at","description","generation","host_ids","id","image_url","podcast_id","published_at","scheduled_at","source_ids","status","title","updated_at","url","video_url"],"description":"A podcast episode with publishing metadata and (when available) audio/video URLs."},"EpisodeStatus":{"type":"string","enum":["draft","published","scheduled"],"description":"Lifecycle state stored on the episode row. Generation progress is reported separately on the `generation` field — `generating`/`completed`/`failed` are not `status` values.","readOnly":true},"CreateEpisodeInput":{"type":"object","properties":{"description":{"type":"string","maxLength":2000},"host_ids":{"type":"array","items":{"type":"string"}},"image":{"type":"string","format":"uri"},"podcast_id":{"type":"string","format":"uuid","description":"Podcast that will own the new episode."},"title":{"type":"string","minLength":1,"maxLength":200}},"required":["podcast_id"],"additionalProperties":false,"description":"Fields for creating an empty episode row. No content is generated."},"AcceptedEpisodeResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"created_at":{"type":"string"},"host_ids":{"type":"array","items":{"type":"string"}},"id":{"type":"string"},"magic_created_host_ids":{"type":"array","items":{"type":"string"},"description":"Subset of host_ids that were magic-created by this import (newly added to the org). Empty when all speakers matched existing hosts."},"podcast_id":{"type":"string"},"status":{"type":"string","enum":["generating"]},"updated_at":{"type":"string"},"workflow_run_id":{"type":"string"}},"required":["created_at","host_ids","id","magic_created_host_ids","podcast_id","status","updated_at","workflow_run_id"]}},"required":["data"],"description":"Acknowledgement for an asynchronously-generated episode."},"GenerateEpisodeInput":{"type":"object","properties":{"host_ids":{"type":"array","items":{"type":"string"},"description":"Hosts to use for generation. In script mode, every segment host_id must be included here, or omit host_ids to infer them from the script.","example":["2e6939fe","a91c4d22"]},"options":{"type":"object","properties":{"episode_length":{"type":"string"},"episode_length_minutes":{"type":"integer","minimum":1,"maximum":75},"web_search":{"type":"boolean","default":true}},"default":{"web_search":true},"description":"Prompt-mode generation options. These are not used when `script` is provided."},"prompt":{"type":"string","minLength":10,"maxLength":10000,"description":"Prompt used to write the episode script. Provide either `prompt` or `script`, not both.","example":"Create a friendly two-host episode about simple habits for a calmer workweek."},"script":{"$ref":"#/components/schemas/ImportedEpisodeScript"},"source_ids":{"type":"array","items":{"type":"string","format":"uuid"},"description":"Source documents for prompt-based generation. Not supported when `script` is provided."},"podcast_id":{"type":"string","format":"uuid","description":"Podcast that will own the generated episode."}},"required":["podcast_id"],"additionalProperties":false,"description":"Fields for generating a new episode asynchronously. Use prompt mode to have Jellypod write the script, or script mode to import a validated structured script."},"ImportedEpisodeScript":{"type":"object","properties":{"chapters":{"type":"array","items":{"$ref":"#/components/schemas/ImportedScriptChapter"},"minItems":1,"maxItems":50,"description":"Ordered script chapters. Maximum 50 chapters."}},"required":["chapters"],"additionalProperties":false,"description":"Structured script input for episode generation. Script mode skips prompt-based script writing. Limits: 75000 total text characters, 50 chapters, 200 segments per chapter, 600 total segments, and 5000 characters per segment.","example":{"chapters":[{"segments":[{"host_id":"2e6939fe","text":"Welcome to the show. Today we are talking about one small habit that can make the week easier."},{"host_id":"a91c4d22","speed":1,"text":"I like that. Let us start with something simple someone can try tomorrow morning."}],"title":"Opening"}]}},"ImportedScriptChapter":{"type":"object","properties":{"segments":{"type":"array","items":{"$ref":"#/components/schemas/ImportedScriptSegment"},"minItems":1,"maxItems":200,"description":"Spoken turns in this chapter. Maximum 200 segments."},"title":{"type":"string","minLength":1,"maxLength":200,"description":"Optional chapter title.","example":"Opening"}},"required":["segments"],"additionalProperties":false,"description":"A group of imported script segments. Each chapter can contain up to 200 segments.","example":{"segments":[{"host_id":"2e6939fe","text":"Welcome to the show. Today we are talking about one small habit that can make the week easier."},{"host_id":"a91c4d22","speed":1,"text":"I like that. Let us start with something simple someone can try tomorrow morning."}],"title":"Opening"}},"ImportedScriptSegment":{"type":"object","properties":{"host_id":{"type":"string","minLength":1,"description":"Host ID for the speaker of this segment.","example":"2e6939fe"},"speed":{"type":"number","minimum":0.5,"maximum":2,"default":1,"description":"Optional playback speed for this segment. Defaults to 1.","example":1},"text":{"type":"string","minLength":1,"maxLength":5000,"description":"Text to synthesize for this segment. Maximum 5000 characters.","example":"Welcome to the show. Today we are talking about one small habit that can make the week easier."}},"required":["host_id","text"],"additionalProperties":false,"description":"One spoken turn in an imported script. The host must belong to your organization.","example":{"host_id":"2e6939fe","speed":1,"text":"Welcome to the show. Today we are talking about one small habit that can make the week easier."}},"ImportEpisodeInput":{"type":"object","properties":{"podcast_id":{"type":"string","format":"uuid","description":"Podcast that will own the imported generated episode."},"script":{"type":"string","minLength":1,"maxLength":75000,"description":"Script or transcript text. Bracketed speaker labels are resolved to existing or newly generated hosts.","example":"[Host One]\nWelcome to the show. Today we are talking about one small habit that can make the week easier.\n\n[Host Two]\nI like that. Let us start with something simple someone can try tomorrow morning."}},"required":["podcast_id","script"],"additionalProperties":false,"description":"Fields for importing script or transcript text and generating a new episode asynchronously."},"UpdateEpisodeInput":{"type":"object","properties":{"description":{"type":["string","null"],"maxLength":2000},"image":{"type":["string","null"],"format":"uri"},"title":{"type":"string","minLength":1,"maxLength":200}},"additionalProperties":false,"description":"Patchable episode fields. All optional; only provided fields are updated."},"UploadEpisodeImageResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string"},"image_url":{"type":"string"}},"required":["id","image_url"]}},"required":["data"],"description":"The uploaded image URL."},"PublishEpisodeResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string"},"scheduled_time":{"type":"string"},"status":{"type":"string","enum":["published","scheduled"]}},"required":["id","status"]}},"required":["data"],"description":"Result of a publish or schedule operation."},"PublishEpisodeInput":{"type":"object","properties":{"scheduled_time":{"type":"string","format":"date-time"}},"additionalProperties":false,"description":"Optional publishing options. Omit to publish immediately; provide `scheduled_time` to schedule for later."},"TimestampsJsonResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"episode_id":{"type":"string"},"speakers":{"type":"array","items":{"type":"object","properties":{"host_id":{"type":"string"},"name":{"type":"string"}},"required":["host_id","name"]}},"words":{"type":"array","items":{"type":"object","properties":{"end":{"type":"number"},"speaker":{"type":["number","null"]},"start":{"type":"number"},"text":{"type":"string"}},"required":["end","speaker","start","text"]}}},"required":["episode_id","speakers","words"]}},"required":["data"],"description":"Word-level episode timestamps with speaker attribution. Speakers are referenced by integer index into the `speakers` array."},"ListHostsResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/HostRow"}}},"required":["data"],"description":"Page of hosts. Use the `Link` response header (`rel=\"next\"`) to paginate."},"HostRow":{"type":"object","properties":{"id":{"type":"string","readOnly":true,"description":"8-character hex host id (e.g. `2e6939fe`).","example":"2e6939fe"},"name":{"type":"string"},"title":{"type":["string","null"]},"backstory":{"type":["string","null"]},"personality":{"type":["string","null"]},"voice_id":{"type":["number","null"]},"voice_model":{"type":["string","null"]},"voice":{"type":["object","null"],"properties":{"accent":{"type":["string","null"]},"description":{"type":["string","null"]},"gender":{"type":"string","enum":["male","female","other"]},"id":{"type":"integer"},"language":{"type":["string","null"]},"model":{"type":["string","null"]},"voice_type":{"type":"string","enum":["professional","clone","design"]}},"required":["accent","description","gender","id","language","model","voice_type"]},"created_at":{"type":"string","readOnly":true},"updated_at":{"type":"string","readOnly":true}},"required":["id","name","title","backstory","personality","voice_id","voice_model","voice","created_at","updated_at"],"description":"A host (speaker/presenter) belonging to your organization."},"CreateHostInput":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100},"voice_id":{"type":"integer"},"title":{"type":"string","minLength":1,"maxLength":100},"personality":{"type":"string","minLength":1,"maxLength":3000},"backstory":{"type":"string","minLength":10,"maxLength":3000},"voice_model":{"type":"string"},"is_guest":{"type":"boolean"},"image_path":{"type":"string"}},"required":["name","voice_id","backstory"],"additionalProperties":false,"description":"Fields required to create a host."},"UpdateHostInput":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100},"voice_id":{"type":"integer"},"title":{"type":"string","minLength":1,"maxLength":100},"personality":{"type":"string","minLength":1,"maxLength":3000},"backstory":{"type":"string","minLength":10,"maxLength":3000},"voice_model":{"type":"string"},"is_guest":{"type":"boolean"},"image_path":{"type":"string"}},"additionalProperties":false,"description":"Patchable host fields. All optional; only provided fields are updated."},"ListPodcastsResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Podcast"}}},"required":["data"],"description":"Page of podcasts. Use the `Link` response header (`rel=\"next\"`) to paginate."},"Podcast":{"type":"object","properties":{"id":{"type":"string","readOnly":true},"title":{"type":"string"},"description":{"type":"string"},"image_url":{"type":["string","null"]},"host_ids":{"type":["array","null"],"items":{"type":"string"}},"languages":{"type":"array","items":{"type":"string"}},"episode_order":{"type":"string","enum":["episodic","serial"],"description":"Episode ordering: `episodic` (standalone) or `serial` (sequential). Always returned lowercase."},"visibility":{"type":["string","null"],"enum":["public","private","unlisted",null],"description":"Visibility. Always returned lowercase."},"url":{"type":"string","readOnly":true},"rss_feed_url":{"type":"string","readOnly":true},"episode_count":{"type":"number","readOnly":true,"description":"Number of episodes that belong to this podcast."},"created_at":{"type":"string","readOnly":true},"updated_at":{"type":"string","readOnly":true}},"required":["id","title","description","image_url","host_ids","languages","episode_order","visibility","url","rss_feed_url","episode_count","created_at","updated_at"],"description":"A podcast in your library with metadata, hosts, languages, and feed URLs."},"CreatePodcastInput":{"type":"object","properties":{"description":{"type":"string"},"episode_order":{"type":"string","enum":["episodic","serial"],"default":"serial"},"host_ids":{"type":"array","items":{"type":"string"},"minItems":1},"language":{"type":"string","pattern":"^[a-zA-Z]{2,3}$","default":"en"},"title":{"type":"string","maxLength":100},"visibility":{"type":"string","enum":["public","private"],"default":"public"}},"required":["host_ids","title"],"additionalProperties":false,"description":"Fields required to create a podcast."},"UpdatePodcastInput":{"type":"object","properties":{"description":{"type":"string"},"episode_order":{"type":"string","enum":["episodic","serial"]},"host_ids":{"type":"array","items":{"type":"string"},"minItems":1},"language":{"type":"string","pattern":"^[a-zA-Z]{2,3}$"},"title":{"type":"string","maxLength":100},"visibility":{"type":"string","enum":["public","private","unlisted"]}},"additionalProperties":false,"description":"Patchable podcast fields. All optional; only provided fields are updated."},"ListSourcesResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/SourceRow"}}},"required":["data"],"description":"Page of sources. Use the `Link` response header (`rel=\"next\"`) to paginate."},"SourceRow":{"type":"object","properties":{"id":{"type":"string","readOnly":true},"title":{"type":["string","null"]},"type":{"type":["string","null"]},"status":{"type":"string","readOnly":true},"metadata":{},"error_message":{"type":["string","null"]},"created_at":{"type":"string","readOnly":true},"updated_at":{"type":"string","readOnly":true}},"required":["id","title","type","status","error_message","created_at","updated_at"],"description":"A content source used as input for episodes."},"AcceptedSourceResponse":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/SourceRow"}},"required":["data"],"description":"Acknowledgement for asynchronous source processing."},"CreateSourceInput":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["url"]},"url":{"type":"string","format":"uri"},"title":{"type":"string"}},"required":["type","url"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","enum":["youtube"]},"url":{"type":"string","format":"uri"},"title":{"type":"string"}},"required":["type","url"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","enum":["text"]},"content":{"type":"string","maxLength":100000},"title":{"type":"string"}},"required":["type","content"],"additionalProperties":false}],"description":"Body for creating a URL, YouTube, or text source. `type` is case-insensitive — the server lowercases it before validation. `url` is required when `type` is `url` or `youtube`; `content` is required when `type` is `text`."},"ListVoicesResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/VoiceRow"}}},"required":["data"],"description":"Page of voices. Use the `Link` response header (`rel=\"next\"`) to paginate."},"VoiceRow":{"type":"object","properties":{"accent":{"type":["string","null"]},"description":{"type":["string","null"]},"gender":{"type":"string","enum":["male","female","other"]},"id":{"type":"integer","description":"Positive integer voice id. Pass this value (as a number, not a string) to `voice_id` on `POST /v1/hosts`.","example":30142,"readOnly":true},"language":{"type":["string","null"],"description":"Language code the voice is filed under: the two-letter ISO 639-1 code where one exists, or the three-letter code where it does not (e.g. \"en\", \"ja\", \"fil\"). New codes appear as the catalog grows, so treat this as an open set rather than a fixed list.","example":"en","readOnly":true},"model":{"type":["string","null"],"description":"Provider-prefixed model string used to synthesize this voice (e.g. \"elevenlabs/eleven_v3\"). Null when the voice has no model configured.","example":"elevenlabs/eleven_v3","readOnly":true},"voice_type":{"type":"string","enum":["professional","clone","design"]}},"required":["accent","description","gender","id","language","model","voice_type"],"description":"A TTS voice available to your organization."}},"parameters":{}},"paths":{"/":{"get":{"operationId":"getApiIndex","security":[],"summary":"API discovery index","tags":["Health"],"responses":{"200":{"description":"Links to the API documentation, spec, and related services.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiIndex"}}}}}}},"/health":{"get":{"operationId":"health","tags":["Health"],"security":[],"responses":{"200":{"description":"Service is healthy","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["ok"]}},"required":["status"]}}}}}}},"/v1/account":{"get":{"operationId":"getAccount","summary":"Get the authenticated organization","tags":["Account"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Authenticated organization details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Account"}}}},"400":{"description":"Validation failed or malformed request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this API key does not have access to this resource.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded. Response includes `Retry-After`, `RateLimit`, and `RateLimit-Policy` headers (IETF draft).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/episodes/{episode_id}/analytics":{"get":{"operationId":"getEpisodeAnalytics","security":[{"bearerAuth":[]}],"summary":"Get streaming analytics for an episode","tags":["Analytics"],"parameters":[{"schema":{"type":"string","format":"uuid","description":"Episode UUID"},"required":true,"description":"Episode UUID","in":"path","name":"episode_id"}],"responses":{"200":{"description":"Episode analytics","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/EpisodeAnalytics"}},"required":["data"]}}}},"400":{"description":"Validation failed or malformed request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this API key does not have access to this resource.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded. Response includes `Retry-After`, `RateLimit`, and `RateLimit-Policy` headers (IETF draft).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/podcasts/{podcast_id}/analytics":{"get":{"operationId":"getPodcastAnalytics","security":[{"bearerAuth":[]}],"summary":"Get streaming analytics for a podcast","tags":["Analytics"],"parameters":[{"schema":{"type":"string","format":"uuid","description":"Podcast UUID"},"required":true,"description":"Podcast UUID","in":"path","name":"podcast_id"}],"responses":{"200":{"description":"Podcast analytics","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/PodcastAnalytics"}},"required":["data"]}}}},"400":{"description":"Validation failed or malformed request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this API key does not have access to this resource.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded. Response includes `Retry-After`, `RateLimit`, and `RateLimit-Policy` headers (IETF draft).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/episodes":{"get":{"operationId":"listEpisodes","security":[{"bearerAuth":[]}],"summary":"List episodes","tags":["Episodes"],"parameters":[{"schema":{"type":"string"},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"podcast_id","in":"query"},{"schema":{"type":"string"},"required":false,"name":"status","in":"query"}],"responses":{"200":{"description":"Page of episodes","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListEpisodesResponse"}}}},"400":{"description":"Validation failed or malformed request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this API key does not have access to this resource.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded. Response includes `Retry-After`, `RateLimit`, and `RateLimit-Policy` headers (IETF draft).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"post":{"description":"Inserts an episode row with only the metadata you provide. No script, audio, or video is generated. Use `POST /v1/episodes/generate` to create an episode and trigger generation in one call.","operationId":"createEpisode","security":[{"bearerAuth":[]}],"summary":"Create an empty episode","tags":["Episodes"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEpisodeInput"}}}},"responses":{"201":{"description":"Episode created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Episode"}},"required":["data"]}}}},"400":{"description":"Validation failed or malformed request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this API key does not have access to this resource.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"415":{"description":"Request `Content-Type` is not supported for this endpoint.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded. Response includes `Retry-After`, `RateLimit`, and `RateLimit-Policy` headers (IETF draft).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/episodes/generate":{"post":{"operationId":"generateEpisode","security":[{"bearerAuth":[]}],"summary":"Generate a new episode (asynchronous)","tags":["Episodes"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateEpisodeInput"}}}},"responses":{"202":{"description":"Episode queued for generation","headers":{"Location":{"description":"Relative URL clients can poll for the accepted resource.","schema":{"type":"string"}},"Retry-After":{"description":"Suggested polling delay in seconds.","schema":{"minimum":1,"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AcceptedEpisodeResponse"}}}},"400":{"description":"Validation failed or malformed request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this API key does not have access to this resource.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"415":{"description":"Request `Content-Type` is not supported for this endpoint.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded. Response includes `Retry-After`, `RateLimit`, and `RateLimit-Policy` headers (IETF draft).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"502":{"description":"The API could not enqueue the downstream asynchronous workflow.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/episodes/import":{"post":{"operationId":"importEpisode","security":[{"bearerAuth":[]}],"summary":"Import script text and generate a new episode (asynchronous)","tags":["Episodes"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportEpisodeInput"}}}},"responses":{"202":{"description":"Imported episode queued for generation","headers":{"Location":{"description":"Relative URL clients can poll for the accepted resource.","schema":{"type":"string"}},"Retry-After":{"description":"Suggested polling delay in seconds.","schema":{"minimum":1,"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AcceptedEpisodeResponse"}}}},"400":{"description":"Validation failed or malformed request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this API key does not have access to this resource.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"415":{"description":"Request `Content-Type` is not supported for this endpoint.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded. Response includes `Retry-After`, `RateLimit`, and `RateLimit-Policy` headers (IETF draft).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"502":{"description":"The API could not enqueue the downstream asynchronous workflow.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/episodes/{episode_id}":{"patch":{"operationId":"updateEpisode","security":[{"bearerAuth":[]}],"summary":"Update episode fields","tags":["Episodes"],"parameters":[{"schema":{"type":"string","format":"uuid","description":"Episode UUID"},"required":true,"description":"Episode UUID","in":"path","name":"episode_id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateEpisodeInput"}},"application/merge-patch+json":{"schema":{"$ref":"#/components/schemas/UpdateEpisodeInput"}}}},"responses":{"200":{"description":"Updated episode","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Episode"}},"required":["data"]}}}},"400":{"description":"Validation failed or malformed request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this API key does not have access to this resource.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"415":{"description":"Request `Content-Type` is not supported for this endpoint.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded. Response includes `Retry-After`, `RateLimit`, and `RateLimit-Policy` headers (IETF draft).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"get":{"operationId":"getEpisode","security":[{"bearerAuth":[]}],"summary":"Get an episode","tags":["Episodes"],"parameters":[{"schema":{"type":"string","format":"uuid","description":"Episode UUID"},"required":true,"description":"Episode UUID","in":"path","name":"episode_id"}],"responses":{"200":{"description":"Episode","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Episode"}},"required":["data"]}}}},"400":{"description":"Validation failed or malformed request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this API key does not have access to this resource.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded. Response includes `Retry-After`, `RateLimit`, and `RateLimit-Policy` headers (IETF draft).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"delete":{"operationId":"deleteEpisode","security":[{"bearerAuth":[]}],"summary":"Delete an episode","tags":["Episodes"],"parameters":[{"schema":{"type":"string","format":"uuid","description":"Episode UUID"},"required":true,"description":"Episode UUID","in":"path","name":"episode_id"}],"responses":{"204":{"description":"Episode deleted"},"400":{"description":"Validation failed or malformed request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this API key does not have access to this resource.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded. Response includes `Retry-After`, `RateLimit`, and `RateLimit-Policy` headers (IETF draft).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/episodes/{episode_id}/image":{"put":{"operationId":"uploadEpisodeImage","security":[{"bearerAuth":[]}],"summary":"Upload an episode cover image (raw image bytes in body)","tags":["Episodes"],"parameters":[{"schema":{"type":"string","format":"uuid","description":"Episode UUID"},"required":true,"description":"Episode UUID","in":"path","name":"episode_id"}],"requestBody":{"description":"Raw image bytes. Set `Content-Type` to `image/jpeg`, `image/png`, or `image/webp`.","required":true,"content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"responses":{"200":{"description":"Image uploaded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadEpisodeImageResponse"}}}},"400":{"description":"Validation failed or malformed request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this API key does not have access to this resource.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"415":{"description":"Request `Content-Type` is not supported for this endpoint.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded. Response includes `Retry-After`, `RateLimit`, and `RateLimit-Policy` headers (IETF draft).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/episodes/{episode_id}/publish":{"post":{"operationId":"publishEpisode","security":[{"bearerAuth":[]}],"summary":"Publish or schedule an episode","tags":["Episodes"],"parameters":[{"schema":{"type":"string","format":"uuid","description":"Episode UUID"},"required":true,"description":"Episode UUID","in":"path","name":"episode_id"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishEpisodeInput"}}}},"responses":{"200":{"description":"Episode published or scheduled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishEpisodeResponse"}}}},"400":{"description":"Validation failed or malformed request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this API key does not have access to this resource.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"415":{"description":"Request `Content-Type` is not supported for this endpoint.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"422":{"description":"Request was well-formed but the resource is in a state that does not allow this operation (e.g. publishing an episode that has not finished rendering).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded. Response includes `Retry-After`, `RateLimit`, and `RateLimit-Policy` headers (IETF draft).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/episodes/{episode_id}/unpublish":{"post":{"operationId":"unpublishEpisode","security":[{"bearerAuth":[]}],"summary":"Unpublish a published or scheduled episode","tags":["Episodes"],"parameters":[{"schema":{"type":"string","format":"uuid","description":"Episode UUID"},"required":true,"description":"Episode UUID","in":"path","name":"episode_id"}],"responses":{"200":{"description":"Episode unpublished","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Episode"}},"required":["data"]}}}},"400":{"description":"Validation failed or malformed request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this API key does not have access to this resource.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"415":{"description":"Request `Content-Type` is not supported for this endpoint.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"422":{"description":"Request was well-formed but the resource is in a state that does not allow this operation (e.g. publishing an episode that has not finished rendering).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded. Response includes `Retry-After`, `RateLimit`, and `RateLimit-Policy` headers (IETF draft).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/episodes/{episode_id}/timestamps":{"get":{"description":"Returns timestamps in the requested `format`. Use `format=json` (default) for structured timestamps, `format=srt` for SubRip, or `format=vtt` for WebVTT.","operationId":"getEpisodeTimestamps","security":[{"bearerAuth":[]}],"summary":"Get episode timestamps","tags":["Episodes"],"parameters":[{"schema":{"type":"string","format":"uuid","description":"Episode UUID"},"required":true,"description":"Episode UUID","in":"path","name":"episode_id"},{"schema":{"type":"string","enum":["json","srt","vtt"],"description":"Response format. `json` returns word-level timestamps with speaker attribution; `srt` returns SubRip; `vtt` returns WebVTT. Defaults to `json`."},"required":false,"description":"Response format. `json` returns word-level timestamps with speaker attribution; `srt` returns SubRip; `vtt` returns WebVTT. Defaults to `json`.","in":"query","name":"format"}],"responses":{"200":{"description":"Timestamps in the requested format. Response `Content-Type` reflects `format`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TimestampsJsonResponse"}},"application/x-subrip":{"schema":{"type":"string"}},"text/vtt":{"schema":{"type":"string"}}}},"400":{"description":"Validation failed or malformed request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this API key does not have access to this resource.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded. Response includes `Retry-After`, `RateLimit`, and `RateLimit-Policy` headers (IETF draft).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/hosts":{"get":{"operationId":"listHosts","summary":"List hosts","tags":["Hosts"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Page of hosts","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListHostsResponse"}}}},"400":{"description":"Validation failed or malformed request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this API key does not have access to this resource.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded. Response includes `Retry-After`, `RateLimit`, and `RateLimit-Policy` headers (IETF draft).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"post":{"operationId":"createHost","summary":"Create a host","tags":["Hosts"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateHostInput"}}}},"responses":{"201":{"description":"Host created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/HostRow"}},"required":["data"]}}}},"400":{"description":"Validation failed or malformed request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this API key does not have access to this resource.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"415":{"description":"Request `Content-Type` is not supported for this endpoint.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded. Response includes `Retry-After`, `RateLimit`, and `RateLimit-Policy` headers (IETF draft).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/hosts/{host_id}":{"get":{"operationId":"getHost","summary":"Get a host","tags":["Hosts"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}$/i","description":"8-character hex host id (e.g. `2e6939fe`).","example":"2e6939fe"},"required":true,"description":"8-character hex host id (e.g. `2e6939fe`).","in":"path","name":"host_id"}],"responses":{"200":{"description":"Host","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/HostRow"}},"required":["data"]}}}},"400":{"description":"Validation failed or malformed request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this API key does not have access to this resource.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded. Response includes `Retry-After`, `RateLimit`, and `RateLimit-Policy` headers (IETF draft).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"patch":{"operationId":"updateHost","summary":"Update a host","tags":["Hosts"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}$/i","description":"8-character hex host id (e.g. `2e6939fe`).","example":"2e6939fe"},"required":true,"description":"8-character hex host id (e.g. `2e6939fe`).","in":"path","name":"host_id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateHostInput"}},"application/merge-patch+json":{"schema":{"$ref":"#/components/schemas/UpdateHostInput"}}}},"responses":{"200":{"description":"Host updated","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/HostRow"}},"required":["data"]}}}},"400":{"description":"Validation failed or malformed request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this API key does not have access to this resource.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"415":{"description":"Request `Content-Type` is not supported for this endpoint.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded. Response includes `Retry-After`, `RateLimit`, and `RateLimit-Policy` headers (IETF draft).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"delete":{"operationId":"deleteHost","summary":"Delete a host","tags":["Hosts"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","pattern":"^[0-9a-f]{8}$/i","description":"8-character hex host id (e.g. `2e6939fe`).","example":"2e6939fe"},"required":true,"description":"8-character hex host id (e.g. `2e6939fe`).","in":"path","name":"host_id"}],"responses":{"204":{"description":"Host deleted"},"400":{"description":"Validation failed or malformed request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this API key does not have access to this resource.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded. Response includes `Retry-After`, `RateLimit`, and `RateLimit-Policy` headers (IETF draft).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/podcasts":{"get":{"operationId":"listPodcasts","summary":"List podcasts","tags":["Podcasts"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Page of podcasts","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListPodcastsResponse"}}}},"400":{"description":"Validation failed or malformed request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this API key does not have access to this resource.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded. Response includes `Retry-After`, `RateLimit`, and `RateLimit-Policy` headers (IETF draft).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"post":{"operationId":"createPodcast","summary":"Create a podcast","tags":["Podcasts"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePodcastInput"}}}},"responses":{"201":{"description":"Podcast created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Podcast"}},"required":["data"]}}}},"400":{"description":"Validation failed or malformed request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this API key does not have access to this resource.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"415":{"description":"Request `Content-Type` is not supported for this endpoint.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded. Response includes `Retry-After`, `RateLimit`, and `RateLimit-Policy` headers (IETF draft).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/podcasts/{podcast_id}":{"get":{"operationId":"getPodcast","summary":"Get a podcast","tags":["Podcasts"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","description":"Podcast UUID"},"required":true,"description":"Podcast UUID","in":"path","name":"podcast_id"}],"responses":{"200":{"description":"Podcast","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Podcast"}},"required":["data"]}}}},"400":{"description":"Validation failed or malformed request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this API key does not have access to this resource.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded. Response includes `Retry-After`, `RateLimit`, and `RateLimit-Policy` headers (IETF draft).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"patch":{"operationId":"updatePodcast","summary":"Update a podcast","tags":["Podcasts"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","description":"Podcast UUID"},"required":true,"description":"Podcast UUID","in":"path","name":"podcast_id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePodcastInput"}},"application/merge-patch+json":{"schema":{"$ref":"#/components/schemas/UpdatePodcastInput"}}}},"responses":{"200":{"description":"Podcast updated","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Podcast"}},"required":["data"]}}}},"400":{"description":"Validation failed or malformed request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this API key does not have access to this resource.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"415":{"description":"Request `Content-Type` is not supported for this endpoint.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded. Response includes `Retry-After`, `RateLimit`, and `RateLimit-Policy` headers (IETF draft).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"delete":{"operationId":"deletePodcast","summary":"Delete a podcast","tags":["Podcasts"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","description":"Podcast UUID"},"required":true,"description":"Podcast UUID","in":"path","name":"podcast_id"}],"responses":{"204":{"description":"Podcast deleted"},"400":{"description":"Validation failed or malformed request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this API key does not have access to this resource.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded. Response includes `Retry-After`, `RateLimit`, and `RateLimit-Policy` headers (IETF draft).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/podcasts/{podcast_id}/image":{"put":{"operationId":"updatePodcastImage","summary":"Replace the podcast cover image","tags":["Podcasts"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","description":"Podcast UUID"},"required":true,"description":"Podcast UUID","in":"path","name":"podcast_id"}],"requestBody":{"required":true,"description":"Raw image bytes. Set `Content-Type` to `image/jpeg`, `image/png`, or `image/webp`.","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"responses":{"200":{"description":"Image updated","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Podcast"}},"required":["data"]}}}},"400":{"description":"Validation failed or malformed request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this API key does not have access to this resource.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"415":{"description":"Request `Content-Type` is not supported for this endpoint.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded. Response includes `Retry-After`, `RateLimit`, and `RateLimit-Policy` headers (IETF draft).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/sources":{"get":{"operationId":"listSources","summary":"List sources","tags":["Sources"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string"},"required":false,"name":"type","in":"query"},{"schema":{"type":"string"},"required":false,"name":"status","in":"query"}],"responses":{"200":{"description":"Page of sources","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListSourcesResponse"}}}},"400":{"description":"Validation failed or malformed request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this API key does not have access to this resource.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded. Response includes `Retry-After`, `RateLimit`, and `RateLimit-Policy` headers (IETF draft).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"post":{"operationId":"createSource","summary":"Create a source from a URL, YouTube link, or text payload","tags":["Sources"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSourceInput"}}}},"responses":{"202":{"description":"Source accepted for processing","headers":{"Location":{"description":"Relative URL clients can poll for the accepted resource.","schema":{"type":"string"}},"Retry-After":{"description":"Suggested polling delay in seconds.","schema":{"minimum":1,"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AcceptedSourceResponse"}}}},"400":{"description":"Validation failed or malformed request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this API key does not have access to this resource.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"415":{"description":"Request `Content-Type` is not supported for this endpoint.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded. Response includes `Retry-After`, `RateLimit`, and `RateLimit-Policy` headers (IETF draft).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"502":{"description":"The API could not enqueue the downstream asynchronous workflow.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/sources/{source_id}":{"get":{"operationId":"getSource","summary":"Get a source","tags":["Sources"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","description":"Source UUID"},"required":true,"description":"Source UUID","in":"path","name":"source_id"}],"responses":{"200":{"description":"Source","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/SourceRow"}},"required":["data"]}}}},"400":{"description":"Validation failed or malformed request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this API key does not have access to this resource.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded. Response includes `Retry-After`, `RateLimit`, and `RateLimit-Policy` headers (IETF draft).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"delete":{"operationId":"deleteSource","summary":"Delete a source","tags":["Sources"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","description":"Source UUID"},"required":true,"description":"Source UUID","in":"path","name":"source_id"}],"responses":{"204":{"description":"Source deleted"},"400":{"description":"Validation failed or malformed request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this API key does not have access to this resource.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded. Response includes `Retry-After`, `RateLimit`, and `RateLimit-Policy` headers (IETF draft).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/voices":{"get":{"operationId":"listVoices","security":[{"bearerAuth":[]}],"summary":"List voices","tags":["Voices"],"parameters":[{"schema":{"type":"string"},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string"},"required":false,"name":"gender","in":"query"},{"schema":{"type":"string","pattern":"^[a-zA-Z]{2,3}$"},"required":false,"name":"language","in":"query"},{"schema":{"type":"string"},"required":false,"name":"voice_type","in":"query"}],"responses":{"200":{"description":"Page of voices","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListVoicesResponse"}}}},"400":{"description":"Validation failed or malformed request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this API key does not have access to this resource.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded. Response includes `Retry-After`, `RateLimit`, and `RateLimit-Policy` headers (IETF draft).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/voices/{voice_id}":{"get":{"operationId":"getVoice","security":[{"bearerAuth":[]}],"summary":"Get a voice","tags":["Voices"],"parameters":[{"schema":{"type":"string","pattern":"^[1-9]\\d*$","description":"Voice ID (positive integer).","example":"30142"},"required":true,"description":"Voice ID (positive integer).","in":"path","name":"voice_id"}],"responses":{"200":{"description":"Voice","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/VoiceRow"}},"required":["data"]}}}},"400":{"description":"Validation failed or malformed request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid API key.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Authenticated, but this API key does not have access to this resource.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Resource not found.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit exceeded. Response includes `Retry-After`, `RateLimit`, and `RateLimit-Policy` headers (IETF draft).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Internal server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}},"webhooks":{}}