{"note":"OpenAPI conversion -- returning structured metadata","name":"zeno-fm","description":"Aggregators API Service","version":"0.84-61bda4d","base_url":"https://api.zeno.fm","endpoints":71,"raw":"@lap v0.3\n# Machine-readable API spec. Each @endpoint block is one API call.\n@api Aggregators API Service\n@base https://api.zeno.fm\n@version 0.84-61bda4d\n@auth ApiKey X-Auth-Token in header\n@endpoints 71\n@hint download_for_search\n@toc podcast-bot(43), api(21), stats(3), partners(4)\n\n@group podcast-bot\n@endpoint GET /podcast-bot/podcasts/{podcastKey}\n@desc Get podcast\n@required {podcastKey: str}\n@returns(200) OK\n\n@endpoint PUT /podcast-bot/podcasts/{podcastKey}\n@desc Update podcast info\n@required {podcastKey: str, title: str, description: str, ownerName: str, ownerEmail: str, categories: [str], language: str}\n@optional {key: str, coverArtUrl: str, summary: str, author: str, link: str, explicit: bool, rssFeed: str, interviewPodcastKey: str}\n@returns(200) OK\n\n@endpoint DELETE /podcast-bot/podcasts/{podcastKey}\n@desc Delete podcast\n@required {podcastKey: str}\n@returns(200) OK\n\n@endpoint PUT /podcast-bot/podcasts/{podcastKey}/recordingSchedule/enable\n@desc Enable podcast recording schedule\n@required {podcastKey: str}\n@returns(200) OK\n\n@endpoint PUT /podcast-bot/podcasts/{podcastKey}/recordingSchedule/disable\n@desc Disable podcast recording schedule\n@required {podcastKey: str}\n@returns(200) OK\n\n@endpoint GET /podcast-bot/podcasts/{podcastKey}/recordingConfig\n@desc Get podcast recording configuration\n@required {podcastKey: str}\n@returns(200) OK\n\n@endpoint PUT /podcast-bot/podcasts/{podcastKey}/recordingConfig\n@desc Update podcast recording configuration\n@required {podcastKey: str, streamUrl: str # Recording audio stream, recordingSchedule: map{frequency!: str, daysOfWeek: [str], daysOfMonth: [int(int32)], startTime!: str, durationMinutes!: int(int64), timezone!: str, enabled: bool} # Podcast Recording Schedule model}\n@optional {introAudioUrl: str # Edit based on intro audio. Required if outro is specified., outroAudioUrl: str # Edit based on outro audio. Required if intro is specified.}\n@returns(200) OK\n\n@endpoint DELETE /podcast-bot/podcasts/{podcastKey}/recordingConfig\n@desc Delete podcast recording configuration\n@required {podcastKey: str}\n@returns(200) OK\n\n@endpoint GET /podcast-bot/podcasts/{podcastKey}/processingPresets\n@desc Get podcast processing presets\n@required {podcastKey: str}\n@returns(200) OK\n\n@endpoint PUT /podcast-bot/podcasts/{podcastKey}/processingPresets\n@desc Update podcast processing presets\n@required {podcastKey: str}\n@optional {removeBackgroundMusic: bool, introAudioUrl: str # Add intro audio to recorded episode, outroAudioUrl: str # Add outro audio to recorded episode, aiTitleSummary: bool # Generate episode title and summary, customPromptTitle: str # Custom prompt for generating episode title, customPromptDescription: str # Custom prompt for generating episode description}\n@returns(200) OK\n\n@endpoint GET /podcast-bot/podcasts/{podcastKey}/interviewPresets\n@desc Get podcast interview extraction presets\n@required {podcastKey: str}\n@returns(200) OK\n\n@endpoint PUT /podcast-bot/podcasts/{podcastKey}/interviewPresets\n@desc Update podcast interview extraction presets\n@required {podcastKey: str}\n@optional {extractInterviews: bool # Enable Interview Extraction, interviewPodcastName: str # Interview Podcast Name. Required if interview extraction is enabled, interviewMinLengthMinutes: int(int64) # Minimum Interview Length (minutes). Required if interview extraction is enabled, customPromptInterviewTitle: str # Custom prompt for generating interview title, customPromptInterviewDescription: str # Custom prompt for generating interview description}\n@returns(200) OK\n\n@endpoint PUT /podcast-bot/podcasts/{podcastKey}/episodes/{episodeKey}/unpublish\n@desc Unpublish podcast episode\n@required {podcastKey: str, episodeKey: str}\n@returns(200) OK\n\n@endpoint PUT /podcast-bot/podcasts/{podcastKey}/episodes/{episodeKey}/publish\n@desc Publish podcast episode\n@required {podcastKey: str, episodeKey: str}\n@returns(200) OK\n\n@endpoint GET /podcast-bot/podcasts/{podcastKey}/autoClipsConfig\n@desc Get auto-clips configuration\n@required {podcastKey: str}\n@returns(200) OK\n\n@endpoint PUT /podcast-bot/podcasts/{podcastKey}/autoClipsConfig\n@desc Update podcast auto-clips configuration\n@required {podcastKey: str}\n@optional {video: map{animation: map, aspect_ratios: [str]} # Video rendering config — used by CREATE_VIDEO and AUTO_CLIP jobs, generate_chapters: bool # Detect YouTube-style chapter boundaries via LLM and upload chapters.json, clip_generation: str # Clip generation mode. \"highlights\" = top viral/engaging moments; \"chapters\" = one clip per chapter boundary (audio only, no transcript/video); \"segments\" = named broadcast blocks (Weather, Sports, Traffic, etc.); \"none\" = skip clip generation, produce chapters only, max_clips: int(int32) # Max number of clips to produce (flat mode only — ignored when `clip_groups` is set), min_clip_duration: num(double) # Minimum clip length in seconds. Clips shorter than this are padded to center. Applies to highlights mode only. (flat mode default; each group can override), max_clip_duration: num(double) # Maximum clip length in seconds. Clips longer than this are trimmed from the end. (flat mode default; each group can override), padding_seconds: num(double) # Extra seconds added before/after each clip, segment_types: [str] # List of broadcast segment names to look for (segments mode only). If empty, LLM infers from content. Fallback value for groups., clip_groups: [map{label: str, video: map, clip_generation: str, count: int(int32), min_clip_duration: num(double), max_clip_duration: num(double), segment_types: [str]}] # List of clip group configs. When set, overrides flat `max_clips`/`min_clip_duration`/`max_clip_duration` and produces multiple named groups of clips.}\n@returns(200) OK\n\n@endpoint DELETE /podcast-bot/podcasts/{podcastKey}/autoClipsConfig\n@desc Delete podcast auto-clips configuration\n@required {podcastKey: str}\n@returns(200) OK\n\n@endpoint GET /podcast-bot/podcasts/{podcastKey}/aiAdsPresets\n@desc Get podcast AI Ads presets\n@required {podcastKey: str}\n@returns(200) OK\n\n@endpoint PUT /podcast-bot/podcasts/{podcastKey}/aiAdsPresets\n@desc Update podcast AI Ads presets\n@required {podcastKey: str}\n@optional {removeAds: bool, insertProgrammaticAds: bool, adsFrequency: int(int64) # Required if insertProgrammaticAds is enabled}\n@returns(200) OK\n\n@endgroup\n\n@group api\n@endpoint GET /api/v2/podcasts/{podcastKey}\n@desc Get podcast\n@required {podcastKey: str}\n@returns(200) OK\n\n@endpoint PUT /api/v2/podcasts/{podcastKey}\n@desc Update podcast\n@required {podcastKey: str}\n@returns(200) OK\n\n@endpoint DELETE /api/v2/podcasts/{podcastKey}\n@desc Delete podcast\n@required {podcastKey: str}\n@returns(200) OK\n\n@endpoint GET /api/v2/podcasts/{podcastKey}/episodes/{episodeKey}\n@desc Get podcast episode\n@required {podcastKey: str, episodeKey: str}\n@returns(200) OK\n\n@endpoint PUT /api/v2/podcasts/{podcastKey}/episodes/{episodeKey}\n@desc Update podcast episode\n@required {podcastKey: str, episodeKey: str}\n@returns(200) OK\n\n@endpoint DELETE /api/v2/podcasts/{podcastKey}/episodes/{episodeKey}\n@desc Delete podcast episode\n@required {podcastKey: str, episodeKey: str}\n@returns(200) OK\n\n@endgroup\n\n@group stats\n@endpoint POST /stats/mounts/{mount}/auth-cache/reload\n@desc Retrieve total numer of live stats for a specific mount\n@required {mount: str}\n@returns(200) OK\n\n@endpoint POST /stats/mounts/{mount}/auth-cache/reload/all\n@desc Retrieve total numer of live stats for a specific mount\n@required {mount: str}\n@returns(200) OK\n\n@endgroup\n\n@group podcast-bot\n@endpoint POST /podcast-bot/workflows/process-file\n@desc Process file\n@optional {fileUrl: str, removeAds: bool, removeBackgroundMusic: bool, removeSilence: bool, normalizeAudioLevels: bool, aiAutoEnhance: bool, removeFillerWords: bool}\n@returns(200) OK\n\n@endpoint POST /podcast-bot/podcasts/{podcastKey}/upload/prerollAudio\n@desc Upload pre-roll audio - prepended to every episode\n@required {podcastKey: str}\n@returns(200) OK\n\n@endpoint POST /podcast-bot/podcasts/{podcastKey}/upload/postrollAudio\n@desc Upload post-roll audio - appended to every episode\n@required {podcastKey: str}\n@returns(200) OK\n\n@endpoint POST /podcast-bot/podcasts/{podcastKey}/upload/editOutroAudio\n@desc Upload outro audio for edit recording\n@required {podcastKey: str}\n@returns(200) OK\n\n@endpoint POST /podcast-bot/podcasts/{podcastKey}/upload/editIntroAudio\n@desc Upload intro audio for edit recording\n@required {podcastKey: str}\n@returns(200) OK\n\n@endpoint POST /podcast-bot/podcasts/{podcastKey}/episodes/{episodeKey}/reprocess\n@desc Reprocess episode\n@required {podcastKey: str, episodeKey: str}\n@returns(200) OK\n\n@endpoint POST /podcast-bot/podcasts/{podcastKey}/episodes/{episodeKey}/reprocess/custom\n@desc Reprocess episode with custom presets\n@required {podcastKey: str, episodeKey: str}\n@optional {cutIntroAudioUrl: str # Edit based on intro audio. Required if cutOutro is specified., cutOutroAudioUrl: str # Edit based on outro audio. Required if cutIntro is specified., addIntroAudioUrl: str # Add intro audio to recorded episode, addOutroAudioUrl: str # Add outro audio to recorded episode, aiTitleSummary: bool # Generate episode title and summary, customPromptTitle: str # Custom prompt for generating episode title, customPromptDescription: str # Custom prompt for generating episode description, removeBackgroundMusic: bool, removeAds: bool, extractInterviews: bool # Enable Interview Extraction, interviewMinLengthMinutes: int(int64) # Minimum Interview Length (minutes). Required if interview extraction is enabled, customPromptInterviewTitle: str # Custom prompt for generating interview title, customPromptInterviewDescription: str # Custom prompt for generating interview description}\n@returns(200) OK\n\n@endpoint POST /podcast-bot/podcasts/recording/create\n@desc Create recording podcast\n@required {podcast: map{key: str, title!: str, coverArtUrl: str, summary: str, description!: str, author: str, ownerName!: str, ownerEmail!: str, categories!: [str], language!: str, link: str, explicit: bool, rssFeed: str, interviewPodcastKey: str} # Podcast model, recordingConfig: map{streamUrl!: str, recordingSchedule!: map, introAudioUrl: str, outroAudioUrl: str} # Podcast Recording Config model}\n@optional {processingPresets: map{removeBackgroundMusic: bool, introAudioUrl: str, outroAudioUrl: str, aiTitleSummary: bool, customPromptTitle: str, customPromptDescription: str} # Podcast Processing Presets model, aiAdsConfig: map{removeAds: bool, insertProgrammaticAds: bool, adsFrequency: int(int64)} # Podcast AI Ads Config model, interviewConfig: map{extractInterviews: bool, interviewPodcastName: str, interviewMinLengthMinutes: int(int64), customPromptInterviewTitle: str, customPromptInterviewDescription: str} # Podcast Interview Config model}\n@returns(200) OK\n\n@endgroup\n\n@group partners\n@endpoint POST /partners/streams\n@desc Get the partner information for a list of streams.\n@required {X-Auth-Token: str}\n@optional {currentTrack: bool=false}\n@returns(200) OK\n\n@endgroup\n\n@group api\n@endpoint POST /api/v2/stations/search\n@desc Search stations\n@optional {query: str, filters: map{country: [str], language: [str], genre: [str]} # Filters for station search, hitsPerPage: int(int32)=10, page: int(int32)=1, minSessions: int(int64)}\n@returns(200) OK\n\n@endpoint POST /api/v2/stations/listener/location\n@desc Get top stations by listener location\n@optional {maxResults: int(int32)=10, continents: [str], countries: [str]}\n@returns(200) OK\n\n@endpoint POST /api/v2/podcasts/{podcastKey}/episodes/create\n@desc Create podcast episode\n@required {podcastKey: str}\n@returns(200) OK\n\n@endpoint POST /api/v2/podcasts/search\n@desc Search podcasts\n@optional {query: str, filters: map{country: [str], language: [str], category: [str], podcastType: str} # Filters for podcast search, hitsPerPage: int(int32)=10, page: int(int32)=1}\n@returns(200) OK\n\n@endpoint POST /api/v2/podcasts/create\n@desc Create podcast\n@returns(200) OK\n\n@endgroup\n\n@group stats\n@endpoint GET /stats/mounts/{mount}/live/total\n@desc Retrieve total numer of live stats for a specific mount\n@required {Authorization: str # Authorization token, mount: str}\n@returns(200) OK\n\n@endgroup\n\n@group podcast-bot\n@endpoint GET /podcast-bot/workflows/{workflowId}/jobsDetails\n@desc Get workflow jobs details\n@required {workflowId: str}\n@returns(200) OK\n\n@endpoint GET /podcast-bot/workflows/{workflowId}/details\n@desc Get workflow details\n@required {workflowId: str}\n@returns(200) OK\n\n@endpoint GET /podcast-bot/podcasts/{podcastKey}/episodes\n@desc Get podcast episodes\n@required {podcastKey: str}\n@optional {limit: str, offset: str}\n@returns(200) OK\n\n@endpoint GET /podcast-bot/podcasts/{podcastKey}/episodes/{episodeKey}\n@desc Get podcast episode\n@required {podcastKey: str, episodeKey: str}\n@returns(200) OK\n\n@endpoint DELETE /podcast-bot/podcasts/{podcastKey}/episodes/{episodeKey}\n@desc Delete podcast episode\n@required {podcastKey: str, episodeKey: str}\n@returns(200) OK\n\n@endpoint GET /podcast-bot/podcasts/{podcastKey}/episodes/{episodeKey}/transcript\n@desc Get transcript for a podcast episode\n@required {podcastKey: str, episodeKey: str}\n@returns(200) OK\n\n@endpoint GET /podcast-bot/podcasts/{podcastKey}/episodes/{episodeKey}/timedTranscript\n@desc Get timed transcript for a podcast episode\n@required {podcastKey: str, episodeKey: str}\n@returns(200) OK\n\n@endpoint GET /podcast-bot/podcasts/{podcastKey}/episodes/{episodeKey}/metadata\n@desc Get metadata for a podcast episode\n@required {podcastKey: str, episodeKey: str}\n@returns(200) OK\n\n@endpoint GET /podcast-bot/podcasts/{podcastKey}/episodes/{episodeKey}/clips\n@desc Get generated clips for a podcast episode\n@required {podcastKey: str, episodeKey: str}\n@returns(200) OK\n\n@endpoint GET /podcast-bot/podcasts/{podcastKey}/episodes/{episodeKey}/chapters\n@desc Get chapters for a podcast episode\n@required {podcastKey: str, episodeKey: str}\n@returns(200) OK\n\n@endpoint GET /podcast-bot/podcasts/{podcastKey}/episodes/{episodeKey}/adsMarkers\n@desc Get Ads markers info for a podcast episode\n@required {podcastKey: str, episodeKey: str}\n@returns(200) OK\n\n@endpoint GET /podcast-bot/podcasts/{podcastKey}/episodes/interviews\n@desc Get podcast interviews\n@required {podcastKey: str}\n@optional {limit: str, offset: str}\n@returns(200) OK\n\n@endpoint GET /podcast-bot/podcasts/list\n@desc List podcasts\n@optional {limit: str, offset: str}\n@returns(200) OK\n\n@endpoint GET /podcast-bot/jobs/{jobId}\n@desc Get job\n@required {jobId: str}\n@returns(200) OK\n\n@endpoint GET /podcast-bot/jobs/podcasts/{podcastKey}\n@desc Get all processing jobs for a podcast\n@required {podcastKey: str}\n@optional {status: str(PENDING_CREATION/PENDING/PROCESSING/CHECKING/FINISHING/CHECKING_FAILED/COMPLETED/FINISHED/FAILED/CANCELLED), from_date: str # Filter jobs where lastUpdate >= from_date (ISO 8601 instant, e.g. 2024-01-01T00:00:00Z)}\n@returns(200) OK\n\n@endpoint GET /podcast-bot/jobs/podcasts/{podcastKey}/episodes/{episodeKey}\n@desc Get processing jobs for a podcast episode\n@required {podcastKey: str, episodeKey: str}\n@returns(200) OK\n\n@endgroup\n\n@group partners\n@endpoint GET /partners/{partnerId}/ads/stats\n@desc Retrieve partner stats\n@required {partnerId: str, from: str(date), to: str(date), x-zeno-api-key: str # Authorization token}\n@optional {type: str(DAILY/HOURLY/BREAKDOWN), page: int(int32)=0, size: int(int32)=10}\n@returns(200) OK\n\n@endpoint GET /partners/streams/{streamId}\n@desc Get the stream partner information.\n@required {streamId: str, X-Auth-Token: str}\n@optional {currentTrack: bool=false}\n@returns(200) OK\n\n@endpoint GET /partners/streams/{streamId}/tracks\n@desc Get the stream partner information.\n@required {streamId: str, X-Auth-Token: str}\n@returns(200) OK\n\n@endgroup\n\n@group api\n@endpoint GET /api/v2/stations/{stationKey}\n@desc Get station\n@required {stationKey: str}\n@returns(200) OK\n\n@endpoint GET /api/v2/stations/list\n@desc List stations\n@optional {page: int(int32)=1, hitsPerPage: int(int32)=10, minSessions: int(int64)}\n@returns(200) OK\n\n@endpoint GET /api/v2/stations/languages\n@desc Get the list of Languages that can be used to filter stations in the search stations request\n@returns(200) OK\n\n@endpoint GET /api/v2/stations/genres\n@desc Get the list of Genres that can be used to filter stations in the search stations request\n@returns(200) OK\n\n@endpoint GET /api/v2/stations/countries\n@desc Get the list of Countries that can be used to filter stations in the search stations request\n@returns(200) OK\n\n@endpoint GET /api/v2/stations/browse\n@desc Browse all stations\n@optional {limit: int(int64)=50, offset: int(int64)=0, mount_status: bool=false}\n@returns(200) OK\n\n@endpoint GET /api/v2/podcasts/{podcastKey}/episodes\n@desc Get podcast episodes\n@required {podcastKey: str}\n@optional {limit: str, offset: str}\n@returns(200) OK\n\n@endpoint GET /api/v2/podcasts/languages\n@desc Get the list of Languages that can be used to filter podcasts in the search podcasts request\n@returns(200) OK\n\n@endpoint GET /api/v2/podcasts/countries\n@desc Get the list of Countries that can be used to filter podcasts in the search podcasts request\n@returns(200) OK\n\n@endpoint GET /api/v2/podcasts/categories\n@desc Get the list of Categories that can be used to filter podcasts in the search podcasts request\n@returns(200) OK\n\n@endgroup\n\n@end\n"}