openapi: 3.0.3
info:
  title: Everlit Auto Audio API
  description: |
    The Auto Audio API enables automatic conversion of web articles into high-quality audio content.

    ## Key Features
    - Automatic content extraction from any URL
    - Multi-language support with automatic voice selection
    - Advanced audio mixing with intro/outro support
    - Smart caching and update detection
    - Conversation mode for multi-voice narration
    - Structured data integration (NEXT_DATA, Fusion CMS, Brightspot)

    ## Getting Started
    1. Obtain API credentials from Everlit support
    2. Make a POST request to `/audio/auto` with your article URL
    3. Poll `/audio/auto/check` until the embed is ready
    4. Embed the returned audio player in your page

    For detailed documentation, visit: https://creator.everlit.audio/docs/auto-audio
  version: 1.13.0
  contact:
    name: Everlit Support
    email: support@everlit.audio
    url: https://everlit.audio
  license:
    name: Proprietary
    url: https://everlit.audio/terms

servers:
  - url: https://creator.everlit.audio
    description: Production server

security:
  - BearerAuth: []

tags:
  - name: Auto Audio
    description: Automatic article to audio conversion

paths:
  /audio/auto:
    post:
      tags:
        - Auto Audio
      summary: Initiate or retrieve audio conversion
      description: |
        Initiates audio conversion for a given URL. This endpoint is asynchronous and will:
        - Return completed embed immediately if already cached
        - Indicate processing is in progress
        - Start a new conversion job if needed

        The response depends on the current state of the conversion:
        - **Cached & Ready**: Returns embed code immediately
        - **Processing**: Returns waiting status
        - **Rate Limited**: Returns rate limit message
        - **Click-to-Create**: Returns widget HTML
      operationId: createAutoAudio
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AutoAudioRequest'
            examples:
              basic:
                summary: Basic conversion request
                value:
                  url: "https://example.com/article"
                  publication_id: "pblc_abc123xyz"
              advanced:
                summary: Advanced with voice and mixing options
                value:
                  url: "https://example.com/article"
                  publication_id: "pblc_abc123xyz"
                  conversation_mode: true
                  sonic_optimizer: true
                  intro_mixable_id: "mixb_intro123"
                  outro_mixable_id: "mixb_outro456"
              with_structured_data:
                summary: With Fusion CMS data
                value:
                  url: "https://example.com/article"
                  publication_id: "pblc_abc123xyz"
                  fusion_data:
                    rawData:
                      headlines:
                        basic: "Breaking News Story"
                      credits:
                        by:
                          - name: "Jane Doe"
                      taxonomy:
                        tags:
                          - text: "Politics"
                    extractedText: "Article content here..."
              server_side_content:
                summary: Server-side content ingestion (bring your own content)
                value:
                  url: "https://example.com/article"
                  publication_id: "pblc_abc123xyz"
                  title: "City Council Approves New Transportation Plan"
                  text: "The city council voted 7-2 on Tuesday to approve a comprehensive transportation plan..."
                  authors: ["Jane Doe", "John Smith"]
                  summary: "A comprehensive look at the council's new transportation plan."
                  category: "Local News"
                  art_url: "https://example.com/images/council.jpg"
                  published_at: "2026-05-29T10:30:00Z"
                  tags: ["transportation", "city-council"]
      responses:
        '200':
          description: Request processed successfully
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/AutoAudioSuccessResponse'
                  - $ref: '#/components/schemas/AutoAudioProcessingResponse'
                  - $ref: '#/components/schemas/AutoAudioClickToCreateResponse'
                  - $ref: '#/components/schemas/AutoAudioErrorResponse'
              examples:
                success:
                  summary: Audio ready
                  value:
                    successful: true
                    embed: "<iframe src=\"https://everlit.audio/embeds/artl_abc123?eut=xyz\" frameborder=\"0\"></iframe>"
                    article_id: "artl_abc123"
                    metadata:
                      title: "Article Title"
                      summary: "Article summary text"
                      duration: 245.5
                    dom_query_params: null
                    published_at: "2025-09-29T10:30:00Z"
                    duration: 245.5
                    title: "Article Title"
                    summary: "Article summary text"
                    authors: ["Jane Doe"]
                    tags: ["category:News", "author:Jane Doe", "language:English"]
                    disclaimer_ui_text: "This audio was generated using AI"
                regenerating:
                  summary: Content updated, re-rendering audio
                  value:
                    successful: true
                    waiting: true
                    regenerating: true
                    message: "Everlit audio is being updated."
                    embed: "<iframe src=\"https://everlit.audio/embeds/artl_abc123?eut=xyz\" frameborder=\"0\"></iframe>"
                    article_id: "artl_abc123"
                processing:
                  summary: Conversion in progress
                  value:
                    successful: true
                    waiting: true
                    message: "Everlit audio conversion is still in progress."
                rate_limited:
                  summary: Rate limit reached
                  value:
                    successful: true
                    reason: "Everlit is already hard at work on this article. Please try again later."
                error:
                  summary: Conversion failed
                  value:
                    successful: false
                    reason: "Unable to fetch the article content."
        '400':
          description: Invalid request format
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AutoAudioErrorResponse'
        '401':
          description: Authentication failed
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: "Unauthorized"
        '403':
          description: Monthly article limit reached
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: "Monthly article limit reached"
                  article_limit:
                    type: integer
                    example: 5
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AutoAudioErrorResponse'

  /audio/auto/check:
    get:
      tags:
        - Auto Audio
      summary: Check audio conversion status
      description: |
        Checks the status of audio conversion for a given URL. This is the recommended
        endpoint for polling conversion status, as it's lightweight and optimized for
        frequent checks.

        **Important**: This endpoint will never initiate a new conversion - it only
        checks existing status. Use POST `/audio/auto` to initiate conversions.

        ## EVP Parameter
        The `evp` query parameter contains URL-safe base64-encoded JSON with the
        following structure:

        ```json
        {
          "url": "https://example.com/article",
          "publication_id": "pblc_abc123xyz",
          "eut": "optional_analytics_token",
          "content_last_published_timestamp": 1698765432000
        }
        ```

        Encode using URL-safe base64 (replace +/= with -_)
      operationId: checkAutoAudioStatus
      parameters:
        - name: evp
          in: query
          required: true
          description: |
            Base64-encoded JSON containing conversion parameters.
            Format: URL-safe base64 (+ → -, / → _, remove =)
          schema:
            type: string
            example: "eyJ1cmwiOiJodHRwczovL2V4YW1wbGUuY29tL2FydGljbGUiLCJwdWJsaWNhdGlvbl9pZCI6InBibGNfYWJjMTIzeHl6In0"
      responses:
        '200':
          description: Status check completed
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/AutoAudioSuccessResponse'
                  - $ref: '#/components/schemas/AutoAudioProcessingResponse'
                  - $ref: '#/components/schemas/AutoAudioCreateNeededResponse'
                  - $ref: '#/components/schemas/AutoAudioClickToCreateResponse'
              examples:
                ready:
                  summary: Audio is ready
                  value:
                    successful: true
                    embed: "<iframe src=\"https://everlit.audio/embeds/artl_abc123\" frameborder=\"0\"></iframe>"
                    article_id: "artl_abc123"
                    metadata:
                      title: "Article Title"
                      summary: "Article summary text"
                      duration: 245.5
                    dom_query_params: null
                processing:
                  summary: Still processing
                  value:
                    successful: true
                    waiting: true
                    message: "Everlit audio conversion is still in progress."
                needs_creation:
                  summary: Conversion not started
                  value:
                    successful: true
                    create: true
                    message: "Conversion is ready."
        '400':
          description: Invalid EVP parameter
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AutoAudioErrorResponse'

components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      description: |
        API authentication using bearer tokens. Contact Everlit support to obtain
        credentials for your publication.

  schemas:
    AutoAudioRequest:
      type: object
      required:
        - url
        - publication_id
      properties:
        url:
          type: string
          format: uri
          description: The URL of the article to convert
          example: "https://example.com/article"
        publication_id:
          type: string
          pattern: '^pblc_[a-zA-Z0-9]+$'
          description: Your publication ID
          example: "pblc_abc123xyz"
        eut:
          type: string
          description: Everlit User Token for analytics tracking (auto-generated if not provided)
          example: "a1b2c3d4e5f6"
        primary_voice_id:
          type: string
          description: Voice ID for primary narrator (overrides publication default)
          example: "voice_professional_en"
        guest_voice_id:
          type: string
          description: Voice ID for guest/secondary narrator
          example: "voice_casual_en"
        conversation_mode:
          type: boolean
          default: false
          description: Enable multi-voice conversation mode
        read_urls:
          type: boolean
          default: false
          description: Read aloud URLs found in content
        read_alt_text:
          type: boolean
          default: false
          description: Read image alt text descriptions
        sonic_optimizer:
          type: boolean
          default: false
          description: Enable Audio Polish for enhanced quality
        optimizer_level:
          type: string
          enum: [light, default, heavy]
          default: default
          description: Audio optimization intensity level
        mix:
          type: boolean
          default: true
          description: Apply background music mixing
        intro_mixable_id:
          type: string
          nullable: true
          description: Custom intro audio mixable ID
          example: "mixb_intro123"
        outro_mixable_id:
          type: string
          nullable: true
          description: Custom outro audio mixable ID
          example: "mixb_outro456"
        intro_duration:
          type: integer
          minimum: 0
          default: 0
          description: Intro audio duration in seconds
        outro_duration:
          type: integer
          minimum: 0
          default: 0
          description: Outro audio duration in seconds
        intro_pad:
          type: integer
          minimum: 0
          default: 0
          description: Silence padding after intro (seconds)
        outro_pad:
          type: integer
          minimum: 0
          default: 0
          description: Silence padding before outro (seconds)
        disclaimer:
          type: string
          nullable: true
          description: Disclaimer text to read before content
          example: "This audio was generated using AI"
        disclaimer_voice_id:
          type: string
          nullable: true
          description: Voice ID for disclaimer narration
        disable_language_detection:
          type: boolean
          default: false
          description: Disable automatic language-based voice selection
        read_author_in_audio_enabled:
          type: boolean
          default: true
          description: Read the author byline aloud in the audio narration
        click_to_create:
          type: boolean
          default: false
          description: Indicates request from click-to-create widget
        dom_content:
          type: string
          nullable: true
          description: Raw page HTML for server-side content extraction (fallback when no structured data is available)
        rendered_html:
          type: string
          nullable: true
          description: Rendered page HTML for server-side extraction of embedded videos and images
        content_last_published_timestamp:
          type: integer
          format: int64
          nullable: true
          description: Article modification timestamp (Unix milliseconds) for update detection
          example: 1698765432000
        next_data:
          type: object
          nullable: true
          description: NEXT_DATA structure from Next.js sites
          properties:
            meta:
              type: object
            hdnDataLayer:
              type: object
            extractedText:
              type: string
        fusion_data:
          type: object
          nullable: true
          description: Fusion CMS (Arc Publishing) data structure
          properties:
            rawData:
              type: object
            extractedText:
              type: string
        brightspot_data:
          type: object
          nullable: true
          description: Brightspot CMS data structure
          properties:
            rawData:
              type: object
            extractedText:
              type: string
        text:
          type: string
          nullable: true
          description: |
            Server-side content ingestion: article body to narrate. When both `text` and `title`
            are supplied, content extraction (scraping) is skipped entirely and this content is used
            verbatim. If only some content fields are supplied, extraction fills the remaining fields.
            Intended for authenticated server-to-server integrations.
        title:
          type: string
          nullable: true
          description: |
            Server-side content ingestion: article headline. Combined with `text`, fully replaces
            content extraction.
        authors:
          type: array
          nullable: true
          items:
            type: string
          description: |
            Server-side content ingestion: author bylines. Normalized, read aloud in the narration,
            and added as `author:` tags.
          example: ["Jane Doe", "John Smith"]
        custom_byline:
          type: string
          nullable: true
          description: |
            Server-side content ingestion: exact byline text to read aloud, overriding the
            auto-generated author string.
        summary:
          type: string
          nullable: true
          description: 'Server-side content ingestion: article summary / description.'
        category:
          type: string
          nullable: true
          description: 'Server-side content ingestion: single section/category, added as a `category:` tag.'
        art_url:
          type: string
          format: uri
          nullable: true
          description: 'Server-side content ingestion: URL of the article artwork/featured image.'
        published_at:
          type: string
          format: date-time
          nullable: true
          description: 'Server-side content ingestion: publication timestamp (ISO 8601), used for deduplication and update detection.'
        tags:
          type: array
          nullable: true
          items:
            type: string
          description: 'Server-side content ingestion: additional pass-through tags (e.g., stock tickers).'

    AutoAudioSuccessResponse:
      type: object
      required:
        - successful
        - embed
      properties:
        successful:
          type: boolean
          enum: [true]
          example: true
        embed:
          type: string
          description: HTML embed code for the audio player
          example: "<iframe src=\"https://everlit.audio/embeds/artl_abc123?eut=xyz\" frameborder=\"0\"></iframe>"
        article_id:
          type: string
          pattern: '^artl_[a-zA-Z0-9]+$'
          description: Everlit article ID (always included)
          example: "artl_abc123"
        metadata:
          type: object
          description: Article metadata (always included for client-side event support)
          properties:
            title:
              type: string
              description: Article title
              example: "Breaking News Story"
            summary:
              type: string
              description: Article summary
              example: "A comprehensive look at recent developments..."
            duration:
              type: number
              format: float
              description: Audio duration in seconds
              example: 245.5
        dom_query_params:
          type: string
          nullable: true
          description: DOM query parameters for widget customization
        published_at:
          type: string
          format: date-time
          description: Article publication timestamp
          example: "2025-09-29T10:30:00Z"
        duration:
          type: number
          format: float
          description: Audio duration in seconds
          example: 245.5
        title:
          type: string
          description: Article title
          example: "Breaking News Story"
        summary:
          type: string
          description: Article summary
          example: "A comprehensive look at recent developments..."
        authors:
          type: array
          items:
            type: string
          description: List of article authors
          example: ["Jane Doe", "John Smith"]
        tags:
          type: array
          items:
            type: string
          description: |
            Article tags including categories, authors, and language.
            Format: "category:Name", "author:Name", "language:Name"
          example: ["category:News", "author:Jane Doe", "language:English"]
        disclaimer_ui_text:
          type: string
          nullable: true
          description: Disclaimer text for display in the UI (separate from the audio disclaimer)
          example: "This audio was generated using AI"
        regenerating:
          type: boolean
          description: When true, audio is being re-rendered due to content updates. The existing cached embed is returned alongside so clients can continue displaying the player.

    AutoAudioProcessingResponse:
      type: object
      required:
        - successful
        - waiting
      properties:
        successful:
          type: boolean
          enum: [true]
        waiting:
          type: boolean
          enum: [true]
        message:
          type: string
          example: "Everlit audio conversion is still in progress."

    AutoAudioCreateNeededResponse:
      type: object
      required:
        - successful
        - create
      properties:
        successful:
          type: boolean
          enum: [true]
        create:
          type: boolean
          enum: [true]
        message:
          type: string
          example: "Conversion is ready."

    AutoAudioClickToCreateResponse:
      type: object
      required:
        - successful
        - click_to_create
      properties:
        successful:
          type: boolean
          enum: [true]
        click_to_create:
          type: boolean
          enum: [true]
        click_to_create_processing:
          type: boolean
          description: Whether audio is currently being created
        click_to_create_embed:
          type: string
          description: HTML for click-to-create widget
          example: "<div>Click to create audio version</div>"

    AutoAudioErrorResponse:
      type: object
      required:
        - successful
      properties:
        successful:
          type: boolean
          enum: [false]
        reason:
          type: string
          description: Error message describing what went wrong
          example: "Unable to fetch the article content."
        create:
          type: boolean
          description: Whether the error occurred during creation
        waiting:
          type: boolean
          description: Whether to retry the request

  examples:
    BasicRequest:
      value:
        url: "https://example.com/article"
        publication_id: "pblc_abc123xyz"
      summary: Minimal conversion request

    AdvancedRequest:
      value:
        url: "https://example.com/article"
        publication_id: "pblc_abc123xyz"
        conversation_mode: true
        sonic_optimizer: true
        intro_mixable_id: "mixb_intro123"
        outro_mixable_id: "mixb_outro456"
        intro_duration: 5
        outro_duration: 3
        read_urls: false
        read_alt_text: true
      summary: Advanced request with mixing options

    FusionDataRequest:
      value:
        url: "https://example.com/article"
        publication_id: "pblc_abc123xyz"
        fusion_data:
          rawData:
            headlines:
              basic: "Article Title"
            credits:
              by:
                - name: "Jane Doe"
                  additional_properties:
                    byline: "Jane Doe, Senior Writer"
            taxonomy:
              tags:
                - text: "Politics"
              sections:
                - name: "News"
            last_updated_date: "2025-09-29T10:30:00Z"
          extractedText: "Full article text content here..."
        content_last_published_timestamp: 1698765432000
      summary: Request with Fusion CMS structured data

x-readme:
  samples-languages:
    - curl
    - javascript
    - python
    - ruby