openapi: 3.0.1 info: title: WellSaid Labs API description: >- REST API for WellSaid Labs AI text-to-speech. Render text to speech using studio-quality voice avatars via synchronous clip creation, low-latency audio streaming, and word-timing renders with subtitles. Authentication is performed with an X-Api-Key request header. termsOfService: https://wellsaidlabs.com/terms/ contact: name: WellSaid Labs Support url: https://docs.wellsaidlabs.com version: '1.0' servers: - url: https://api.wellsaidlabs.com/v1 security: - ApiKeyAuth: [] tags: - name: Text-to-Speech description: Render text to speech as clips or audio streams. - name: Clips description: Manage rendered clips. - name: Voices description: Discover available voice avatars. - name: Pronunciation description: Respelling suggestions and replacement libraries. paths: /tts/stream: post: operationId: streamTextToSpeech tags: - Text-to-Speech summary: Render text to speech as an audio stream. description: >- Renders the supplied text to speech with the chosen voice avatar and streams the result back as an audio/mpeg (MP3) stream as it is produced. parameters: - name: X-Enable-SSML in: header required: false description: Enables limited SSML translation for the input text. schema: type: boolean - name: Accept in: header required: false description: Desired audio media type for the streamed response. schema: type: string default: audio/mpeg requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/RenderRequest' responses: '200': description: Audio stream from a successful text-to-speech render. content: audio/mpeg: schema: type: string format: binary '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' '508': description: >- Render loop detected. Likely a result of unusual phrasing, characters, and/or punctuation in the input text. /tts/clips: post: operationId: createClip tags: - Text-to-Speech - Clips summary: Create a new TTS clip asynchronously. description: >- Submits a text-to-speech render request and creates a clip that is produced asynchronously. Poll the clip endpoint to retrieve status and the rendered audio. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/RenderRequest' responses: '200': description: The created clip. content: application/json: schema: $ref: '#/components/schemas/Clip' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' get: operationId: listClips tags: - Clips summary: Get a list of recent clips. responses: '200': description: A list of recent clips. content: application/json: schema: type: array items: $ref: '#/components/schemas/Clip' '401': $ref: '#/components/responses/Unauthorized' /tts/clips/{clip-id}: get: operationId: getClip tags: - Clips summary: Get information about a single clip. parameters: - name: clip-id in: path required: true schema: type: string responses: '200': description: Information about a single clip. content: application/json: schema: $ref: '#/components/schemas/Clip' '401': $ref: '#/components/responses/Unauthorized' '404': description: Clip not found. /tts/clips/combine: post: operationId: combineClips tags: - Clips summary: Combine a list of clips into a single file with pauses. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CombineClipsRequest' responses: '200': description: Combined audio file. content: audio/mpeg: schema: type: string format: binary '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' /tts/word-timing: post: operationId: renderWordTiming tags: - Text-to-Speech summary: Render text to speech with timing information and subtitles. description: >- Renders the supplied text to speech and returns a zip file containing the generated audio along with word-level timing as JSON, SRT, and VTT subtitle files. parameters: - name: X-Enable-SSML in: header required: false description: Enables limited SSML translation for the input text. schema: type: boolean requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/RenderRequest' responses: '200': description: >- Zip archive containing the rendered audio plus JSON, SRT, and VTT timing files. content: application/zip: schema: type: string format: binary '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '429': $ref: '#/components/responses/TooManyRequests' '508': description: Render loop detected. /tts/avatars: get: operationId: getAvatars tags: - Voices summary: Get available voice avatars. description: >- Returns the list of available voice avatars with their speaker_id, name, accent, and speaking style for selecting a voice to render with. responses: '200': description: A list of available voice avatars. content: application/json: schema: type: array items: $ref: '#/components/schemas/Avatar' '401': $ref: '#/components/responses/Unauthorized' /tts/respelling-suggestions: get: operationId: getRespellingSuggestions tags: - Pronunciation summary: Get respelling suggestions. description: >- Returns suggested respellings that shape the pronunciation of a word for use in renders or replacement libraries. parameters: - name: word in: query required: false schema: type: string responses: '200': description: Respelling suggestions. content: application/json: schema: type: array items: type: string '401': $ref: '#/components/responses/Unauthorized' /tts/replacement-libraries: get: operationId: listReplacementLibraries tags: - Pronunciation summary: Get list of available replacement libraries. responses: '200': description: A list of replacement libraries. content: application/json: schema: type: array items: $ref: '#/components/schemas/ReplacementLibrary' '401': $ref: '#/components/responses/Unauthorized' post: operationId: createReplacementLibrary tags: - Pronunciation summary: Create a new replacement library. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ReplacementLibrary' responses: '200': description: The created replacement library. content: application/json: schema: $ref: '#/components/schemas/ReplacementLibrary' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' /tts/replacement-libraries/{library-id}: get: operationId: getReplacementLibrary tags: - Pronunciation summary: Get information about a single replacement library. parameters: - name: library-id in: path required: true schema: type: string responses: '200': description: A single replacement library. content: application/json: schema: $ref: '#/components/schemas/ReplacementLibrary' '401': $ref: '#/components/responses/Unauthorized' '404': description: Replacement library not found. delete: operationId: deleteReplacementLibrary tags: - Pronunciation summary: Delete a replacement library. parameters: - name: library-id in: path required: true schema: type: string responses: '204': description: Replacement library deleted. '401': $ref: '#/components/responses/Unauthorized' '404': description: Replacement library not found. /tts/replacement-libraries/{library-id}/replacements: get: operationId: listReplacements tags: - Pronunciation summary: Get list of replacements in a library. parameters: - name: library-id in: path required: true schema: type: string responses: '200': description: A list of replacements. content: application/json: schema: type: array items: $ref: '#/components/schemas/Replacement' '401': $ref: '#/components/responses/Unauthorized' post: operationId: createReplacement tags: - Pronunciation summary: Create a new replacement in a library. parameters: - name: library-id in: path required: true schema: type: string requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Replacement' responses: '200': description: The created replacement. content: application/json: schema: $ref: '#/components/schemas/Replacement' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' /tts/replacement-libraries/{library-id}/replacements/{replacement-id}: get: operationId: getReplacement tags: - Pronunciation summary: Get details of a replacement. parameters: - name: library-id in: path required: true schema: type: string - name: replacement-id in: path required: true schema: type: string responses: '200': description: A single replacement. content: application/json: schema: $ref: '#/components/schemas/Replacement' '401': $ref: '#/components/responses/Unauthorized' '404': description: Replacement not found. delete: operationId: deleteReplacement tags: - Pronunciation summary: Delete a replacement. parameters: - name: library-id in: path required: true schema: type: string - name: replacement-id in: path required: true schema: type: string responses: '204': description: Replacement deleted. '401': $ref: '#/components/responses/Unauthorized' '404': description: Replacement not found. components: securitySchemes: ApiKeyAuth: type: apiKey in: header name: X-Api-Key responses: BadRequest: description: Request failed input validation. Unauthorized: description: API key missing or invalid. TooManyRequests: description: Rate limit exceeded. schemas: RenderRequest: type: object required: - speaker_id - text properties: speaker_id: type: integer description: Identifier of the voice avatar (speaker) to render with. example: 50 text: type: string minLength: 1 maxLength: 1000 description: The input text to render to speech. example: I love building and shipping new features for our users! model: type: string enum: - legacy - caruso description: The TTS model to render with. library_ids: type: array description: Optional replacement library identifiers to apply during the render. items: type: string audio_configs: type: object description: Optional audio configuration settings for the render. additionalProperties: true Clip: type: object properties: id: type: string status: type: string description: Processing status of the asynchronous render. speaker_id: type: integer text: type: string url: type: string description: URL of the rendered audio when available. CombineClipsRequest: type: object required: - clip_ids properties: clip_ids: type: array items: type: string pause: type: number description: Pause in seconds inserted between combined clips. Avatar: type: object properties: speaker_id: type: integer avatar_id: type: integer name: type: string accent: type: string style: type: string description: Speaking style of the voice avatar. ReplacementLibrary: type: object properties: id: type: string name: type: string Replacement: type: object properties: id: type: string original: type: string description: The original word or phrase to replace. replacement: type: string description: The respelling or replacement applied during rendering.