WellSaid Labs Pronunciation API

Manage pronunciation across renders. Create and manage replacement libraries and the individual replacements inside them so brand names, acronyms, and jargon are spoken consistently, and fetch respelling suggestions that help coax the correct pronunciation of a difficult word.

OpenAPI Specification

wellsaid-labs-openapi.yml Raw ↑
openapi: 3.0.3
info:
  title: WellSaid Labs API
  description: >-
    The WellSaid Labs API renders text into studio-quality AI voiceover. It
    exposes streaming text-to-speech (audio returned as an HTTP stream for low
    time-to-first-byte playback), word-level timing and subtitle rendering,
    asynchronous clip creation and combination, a catalog of voice avatars, and
    pronunciation control via replacement libraries and respelling suggestions.
    All requests authenticate with an X-Api-Key header. WellSaid does not
    currently support end-user authentication and recommends making requests
    from an internal or trusted source. API access is gated behind a trial API
    key and a business plan. Endpoints, request fields, and response shapes here
    are modeled from the public documentation at docs.wellsaidlabs.com and are
    honestly approximated where the reference does not publish a full schema.
  version: '1.0'
  contact:
    name: WellSaid Labs
    url: https://wellsaidlabs.com
servers:
  - url: https://api.wellsaidlabs.com/v1
    description: WellSaid Labs API
security:
  - apiKeyAuth: []
tags:
  - name: Text-to-Speech
    description: Render text to speech, with streaming audio and word timing.
  - name: Clips
    description: Asynchronous clip creation, retrieval, and combination.
  - name: Voice Avatars
    description: Catalog of available AI voice avatars and their metadata.
  - name: Pronunciation
    description: Replacement libraries and respelling suggestions for pronunciation control.
paths:
  /tts/stream:
    post:
      operationId: renderTtsStream
      tags:
        - Text-to-Speech
      summary: Render text to speech (streaming)
      description: >-
        Renders the supplied text with the chosen voice avatar and returns the
        result as a stream of an audio file (MP3), not the finished file, so the
        client can begin playback with a low time-to-first-byte. Default keys are
        limited to 1,000 characters per request. Accepts a subset of SSML tags.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TtsRequest'
      responses:
        '200':
          description: A stream of the rendered audio.
          content:
            audio/mpeg:
              schema:
                type: string
                format: binary
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/RateLimited'
  /word-timing:
    post:
      operationId: renderWordTiming
      tags:
        - Text-to-Speech
      summary: Render text to speech with timing information
      description: >-
        Renders text to speech and returns the audio together with word-level
        timing information and subtitles, so captions can be aligned to the
        generated voiceover.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TtsRequest'
      responses:
        '200':
          description: Rendered audio with word timing and subtitle data.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WordTimingResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/RateLimited'
  /clips:
    get:
      operationId: listClips
      tags:
        - Clips
      summary: List recent clips
      description: Returns a list of recently created text-to-speech clips.
      responses:
        '200':
          description: A list of clips.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Clip'
        '401':
          $ref: '#/components/responses/Unauthorized'
    post:
      operationId: createClip
      tags:
        - Clips
      summary: Create a clip asynchronously
      description: >-
        Creates a new text-to-speech clip asynchronously. The clip is rendered in
        the background; poll the clip by id to retrieve its status and audio.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TtsRequest'
      responses:
        '202':
          description: The clip was accepted for asynchronous rendering.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Clip'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/RateLimited'
  /clips/{clip_id}:
    get:
      operationId: getClip
      tags:
        - Clips
      summary: Get a single clip
      description: Returns information about a single clip, including its render status and audio URL.
      parameters:
        - $ref: '#/components/parameters/ClipId'
      responses:
        '200':
          description: The requested clip.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Clip'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
  /clips/combine:
    post:
      operationId: combineClips
      tags:
        - Clips
      summary: Combine clips into one file
      description: >-
        Combines a list of clips into a single audio file, inserting pauses
        between them. Useful for assembling longer-form voiceover from many
        rendered segments.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                clip_ids:
                  type: array
                  items:
                    type: string
                  description: The ids of the clips to combine, in order.
                pause:
                  type: number
                  format: float
                  description: Pause in seconds to insert between clips.
              required:
                - clip_ids
      responses:
        '200':
          description: The combined audio file (or a clip referencing it).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Clip'
        '401':
          $ref: '#/components/responses/Unauthorized'
  /avatars:
    get:
      operationId: listAvatars
      tags:
        - Voice Avatars
      summary: Get available voice avatars
      description: >-
        Lists all available voice avatars with their metadata - the numeric
        speaker id, avatar name, style, language, accent, descriptive
        characteristics, and compatible models.
      responses:
        '200':
          description: A list of voice avatars.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Avatar'
        '401':
          $ref: '#/components/responses/Unauthorized'
  /replacement-libraries:
    get:
      operationId: listReplacementLibraries
      tags:
        - Pronunciation
      summary: List replacement libraries
      description: Returns the list of available pronunciation replacement libraries.
      responses:
        '200':
          description: A list of replacement libraries.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/ReplacementLibrary'
        '401':
          $ref: '#/components/responses/Unauthorized'
    post:
      operationId: createReplacementLibrary
      tags:
        - Pronunciation
      summary: Create a replacement library
      description: Creates a new replacement library for grouping pronunciation replacements.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  description: A human-readable name for the library.
              required:
                - name
      responses:
        '201':
          description: The created replacement library.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReplacementLibrary'
        '401':
          $ref: '#/components/responses/Unauthorized'
  /replacement-libraries/{library_id}:
    get:
      operationId: getReplacementLibrary
      tags:
        - Pronunciation
      summary: Get a replacement library
      description: Returns information about a single replacement library.
      parameters:
        - $ref: '#/components/parameters/LibraryId'
      responses:
        '200':
          description: The requested replacement library.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReplacementLibrary'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
    delete:
      operationId: deleteReplacementLibrary
      tags:
        - Pronunciation
      summary: Delete a replacement library
      description: Deletes a replacement library and its replacements.
      parameters:
        - $ref: '#/components/parameters/LibraryId'
      responses:
        '204':
          description: The replacement library was deleted.
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
  /replacement-libraries/{library_id}/replacements:
    get:
      operationId: listReplacements
      tags:
        - Pronunciation
      summary: List replacements in a library
      description: Returns the list of replacements contained in a replacement library.
      parameters:
        - $ref: '#/components/parameters/LibraryId'
      responses:
        '200':
          description: A list of replacements.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Replacement'
        '401':
          $ref: '#/components/responses/Unauthorized'
    post:
      operationId: createReplacement
      tags:
        - Pronunciation
      summary: Create a replacement
      description: Creates a new pronunciation replacement in the library.
      parameters:
        - $ref: '#/components/parameters/LibraryId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ReplacementInput'
      responses:
        '201':
          description: The created replacement.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Replacement'
        '401':
          $ref: '#/components/responses/Unauthorized'
  /replacement-libraries/{library_id}/replacements/{replacement_id}:
    get:
      operationId: getReplacement
      tags:
        - Pronunciation
      summary: Get a replacement
      description: Returns a single replacement from a library.
      parameters:
        - $ref: '#/components/parameters/LibraryId'
        - $ref: '#/components/parameters/ReplacementId'
      responses:
        '200':
          description: The requested replacement.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Replacement'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
    delete:
      operationId: deleteReplacement
      tags:
        - Pronunciation
      summary: Delete a replacement
      description: Removes a replacement from a library.
      parameters:
        - $ref: '#/components/parameters/LibraryId'
        - $ref: '#/components/parameters/ReplacementId'
      responses:
        '204':
          description: The replacement was deleted.
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
  /respelling-suggestions:
    get:
      operationId: getRespellingSuggestions
      tags:
        - Pronunciation
      summary: Get respelling suggestions
      description: >-
        Returns respelling suggestions for a word to help coax the correct
        pronunciation from the voice avatar.
      parameters:
        - name: word
          in: query
          required: true
          schema:
            type: string
          description: The word to get respelling suggestions for.
      responses:
        '200':
          description: A list of respelling suggestions.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      type: string
        '401':
          $ref: '#/components/responses/Unauthorized'
components:
  securitySchemes:
    apiKeyAuth:
      type: apiKey
      in: header
      name: X-Api-Key
      description: >-
        API key issued by WellSaid Labs, passed in the X-Api-Key header. Request
        a trial key from the console; production use requires a business plan.
  parameters:
    ClipId:
      name: clip_id
      in: path
      required: true
      schema:
        type: string
      description: The id of the clip.
    LibraryId:
      name: library_id
      in: path
      required: true
      schema:
        type: string
      description: The id of the replacement library.
    ReplacementId:
      name: replacement_id
      in: path
      required: true
      schema:
        type: string
      description: The id of the replacement.
  responses:
    Unauthorized:
      description: Missing or invalid X-Api-Key.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    NotFound:
      description: The requested resource was not found.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    RateLimited:
      description: >-
        Rate limit or monthly character quota exceeded. Inspect the
        x-rate-limit-* and x-quota-* response headers.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  schemas:
    TtsRequest:
      type: object
      properties:
        text:
          type: string
          description: The text to convert to speech. Default keys allow up to 1,000 characters per request.
        speaker_id:
          type: string
          description: The voice avatar (speaker) id to render with, for example "3".
        model:
          type: string
          description: The voice model to use, for example "caruso" or "legacy".
      required:
        - text
        - speaker_id
    WordTimingResponse:
      type: object
      properties:
        audio_url:
          type: string
          description: URL to the rendered audio.
        subtitles:
          type: string
          description: Subtitle text aligned to the audio.
        words:
          type: array
          description: Per-word timing entries.
          items:
            type: object
            properties:
              word:
                type: string
              start:
                type: number
                format: float
                description: Start time in seconds.
              end:
                type: number
                format: float
                description: End time in seconds.
    Clip:
      type: object
      properties:
        id:
          type: string
          description: The clip id.
        status:
          type: string
          description: Render status of the clip, for example "processing" or "complete".
        text:
          type: string
        speaker_id:
          type: string
        audio_url:
          type: string
          description: URL to the rendered audio once the clip is complete.
        created_at:
          type: string
          format: date-time
    Avatar:
      type: object
      properties:
        id:
          type: integer
          description: The numeric speaker id used as speaker_id in render requests.
        name:
          type: string
          description: The voice avatar name, for example "Alana B.".
        style:
          type: string
          description: Voice style such as Narration, Promo, Conversational, or Character.
        language:
          type: string
        accent:
          type: string
          description: Accent or region, for example "United States" or "England".
        characteristics:
          type: array
          items:
            type: string
          description: Descriptive tags such as "Clear", "Crisp", "Focused".
        models:
          type: array
          items:
            type: string
          description: Compatible models such as "caruso" and "legacy".
    ReplacementLibrary:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        created_at:
          type: string
          format: date-time
    ReplacementInput:
      type: object
      properties:
        original:
          type: string
          description: The original word or phrase to replace.
        replacement:
          type: string
          description: The respelled or substitute pronunciation to speak instead.
      required:
        - original
        - replacement
    Replacement:
      type: object
      properties:
        id:
          type: string
        original:
          type: string
        replacement:
          type: string
    Error:
      type: object
      properties:
        message:
          type: string
        code:
          type: string