{"openapi":"3.1.0","info":{"title":"Audio Converter API","description":"Audio file format conversion service using FFMPEG for the Haiven infrastructure.\n\nConverts any audio format supported by FFMPEG to MP3 or WAV. Designed primarily\nfor speech-to-text transcription pipelines, with WAV output optimized for ASR\n(16kHz, 16-bit PCM).\n\n## Features\n- Wide input format support (MP3, WAV, FLAC, OGG, M4A, AAC, WMA, OPUS, WebM, etc.)\n- Output to MP3 (128k/192k/320k) or WAV (16kHz PCM)\n- Pipeline integration via webhooks\n- URL-based conversion for automation\n","version":"1.0.0","contact":{"name":"Haiven Support"},"license":{"name":"Apache 2.0"}},"servers":[{"url":"https://audio-converter.haiven.site","description":"Production server (via Traefik)"},{"url":"https://audio-converter.haiven.site","description":"External access (Let's Encrypt SSL)"},{"url":"http://audio-converter:5003","description":"Internal Docker network"}],"tags":[{"name":"Conversion","description":"Audio format conversion operations"},{"name":"Information","description":"Format and service information"},{"name":"Health","description":"Service health checks"},{"name":"Download","description":"File download operations"}],"paths":{"/":{"get":{"tags":["Information"],"summary":"Web UI","description":"Render the web-based upload interface for audio conversion","operationId":"webUI","responses":{"200":{"description":"HTML page for file upload and conversion","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/health":{"get":{"tags":["Health"],"summary":"Health check","description":"Verify service is running","operationId":"healthCheck","responses":{"200":{"description":"Service is healthy","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatus"},"example":{"status":"healthy","service":"audio-converter"}}}}}}},"/formats":{"get":{"tags":["Information"],"summary":"List supported formats","description":"Get list of supported input formats, output formats, and quality presets","operationId":"listFormats","responses":{"200":{"description":"Format information","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FormatInfo"},"example":{"input":"All formats supported by FFMPEG (mp3, wav, flac, ogg, m4a, aac, wma, opus, webm, etc.)","output":["mp3","wav"],"quality_presets":["low","medium","high"]}}}}}}},"/convert":{"post":{"tags":["Conversion"],"summary":"Convert uploaded audio file","description":"Convert an uploaded audio file to MP3 or WAV format.\n\nSupports optional webhook integration for pipeline processing - the converted\nfile will be POSTed to the webhook URL with metadata.\n\nSet `return_file=true` to receive the converted audio directly instead of JSON.\n","operationId":"convertAudio","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary","description":"Audio file to convert (max 500MB)"},"format":{"type":"string","enum":["mp3","wav"],"default":"wav","description":"Target audio format"},"quality":{"type":"string","enum":["low","medium","high"],"default":"high","description":"Quality preset (affects MP3 bitrate: low=128k, medium=192k, high=320k)"},"webhook_url":{"type":"string","format":"uri","description":"Optional URL to POST converted file to for pipeline processing","example":"https://whisper.haiven.site/v1/audio/transcriptions"},"return_file":{"type":"string","enum":["true","false"],"default":"false","description":"If 'true', return the converted file directly instead of JSON response"}}}}}},"responses":{"200":{"description":"Successfully converted audio file","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConversionResult"},"example":{"success":true,"original_filename":"podcast.mp3","converted_filename":"podcast_a1b2c3d4.wav","format":"wav","quality":"high","download_url":"/download/podcast_a1b2c3d4.wav","pipeline_result":null}},"audio/mpeg":{"schema":{"type":"string","format":"binary"},"description":"Returned when format=mp3 and return_file=true"},"audio/wav":{"schema":{"type":"string","format":"binary"},"description":"Returned when format=wav and return_file=true"}}},"400":{"description":"Invalid input parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"no_file":{"summary":"No file provided","value":{"error":"No file provided"}},"invalid_format":{"summary":"Invalid format","value":{"error":"Invalid format. Use mp3 or wav"}}}}}},"413":{"description":"File too large (max 500MB)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Conversion failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"Conversion failed: ffmpeg error message"}}}}}}},"/api/convert":{"post":{"tags":["Conversion"],"summary":"Convert audio from URL","description":"Fetch audio from a URL and convert it. Useful for pipeline automation\nand processing remote files without downloading them first.\n","operationId":"convertFromUrl","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri","description":"URL to fetch audio from","example":"https://example.com/audio.m4a"},"format":{"type":"string","enum":["mp3","wav"],"default":"wav","description":"Target audio format"},"quality":{"type":"string","enum":["low","medium","high"],"default":"high","description":"Quality preset"},"webhook_url":{"type":"string","format":"uri","description":"Optional URL to POST converted file to"}}}}}},"responses":{"200":{"description":"Successfully converted audio","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiConversionResult"},"example":{"success":true,"converted_filename":"a1b2c3d4.wav","download_url":"/download/a1b2c3d4.wav","pipeline_result":null}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"no_json":{"summary":"JSON body required","value":{"error":"JSON body required"}},"no_url":{"summary":"URL required","value":{"error":"url field required"}}}}}},"500":{"description":"Conversion failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/download/{filename}":{"get":{"tags":["Download"],"summary":"Download converted file","description":"Download a previously converted audio file by filename","operationId":"downloadFile","parameters":[{"name":"filename","in":"path","required":true,"description":"Name of the converted file to download","schema":{"type":"string"},"example":"podcast_a1b2c3d4.wav"}],"responses":{"200":{"description":"Audio file","content":{"audio/mpeg":{"schema":{"type":"string","format":"binary"}},"audio/wav":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"Invalid path","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"Invalid path"}}}},"404":{"description":"File not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"File not found"}}}}}}}},"components":{"schemas":{"HealthStatus":{"type":"object","description":"Service health status","required":["status","service"],"properties":{"status":{"type":"string","description":"Health status","example":"healthy"},"service":{"type":"string","description":"Service name","example":"audio-converter"}}},"FormatInfo":{"type":"object","description":"Supported format information","required":["input","output","quality_presets"],"properties":{"input":{"type":"string","description":"Description of supported input formats"},"output":{"type":"array","items":{"type":"string"},"description":"List of supported output formats"},"quality_presets":{"type":"array","items":{"type":"string"},"description":"Available quality presets"}}},"ConversionResult":{"type":"object","description":"Result of file conversion","required":["success","original_filename","converted_filename","format","quality","download_url"],"properties":{"success":{"type":"boolean","description":"Whether conversion was successful"},"original_filename":{"type":"string","description":"Original uploaded filename"},"converted_filename":{"type":"string","description":"Name of converted file"},"format":{"type":"string","description":"Output format used"},"quality":{"type":"string","description":"Quality preset used"},"download_url":{"type":"string","description":"URL path to download converted file"},"pipeline_result":{"type":"object","nullable":true,"description":"Response from webhook if webhook_url was provided"}}},"ApiConversionResult":{"type":"object","description":"Result of URL-based conversion","required":["success","converted_filename","download_url"],"properties":{"success":{"type":"boolean","description":"Whether conversion was successful"},"converted_filename":{"type":"string","description":"Name of converted file"},"download_url":{"type":"string","description":"URL path to download converted file"},"pipeline_result":{"type":"object","nullable":true,"description":"Response from webhook if webhook_url was provided"}}},"ErrorResponse":{"type":"object","description":"Error response","required":["error"],"properties":{"error":{"type":"string","description":"Error message"}}}}}}