> ## Documentation Index
> Fetch the complete documentation index at: https://typecast.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# 조합형 텍스트 음성 변환(Compose TTS)

> 여러 음성 구간과 쉼을 하나의 오디오 파일로 생성합니다. `segments` 배열에 `tts`와 `pause` 객체를 재생할 순서대로 넣으세요. 각 `tts` 세그먼트는 `POST /v1/text-to-speech`와 동일한 보이스, 모델, 감정, 출력 설정을 지원하며 세그먼트마다 다른 보이스와 모델을 사용할 수 있습니다.

**제한**
- 전체 세그먼트는 최대 50개이며 `tts` 세그먼트가 최소 1개 필요합니다.
- 모든 `tts` 세그먼트의 텍스트 합은 최대 2,000자입니다.
- 쉼은 개별 최대 10초, 전체 합계 최대 60초입니다.
- 모든 `tts` 세그먼트의 `audio_format`은 같아야 합니다.

크레딧은 `tts` 텍스트 길이의 합만큼 차감되며 쉼에는 차감되지 않습니다. 세그먼트는 병렬로 합성된 뒤 입력 순서대로 반환됩니다. 하나라도 합성에 실패하면 전체 요청이 실패하며 크레딧은 차감되지 않습니다.

**응답**
성공하면 JSON이 아닌 합성된 오디오 바이너리 데이터를 직접 반환합니다. 응답의 `Content-Type`은 세그먼트에서 요청한 `audio_format`에 따라 `audio/wav` 또는 `audio/mpeg`입니다.



## OpenAPI

````yaml /ko/api-reference/openapi.json post /v1/text-to-speech/compose
openapi: 3.1.0
info:
  title: Typecast API
  version: 0.1.2
  x-logo:
    url: https://typecast.ai/docs/logo/light.svg
servers:
  - url: https://api.typecast.ai
    description: 프로덕션 서버
security:
  - ApiKeyAuth: []
paths:
  /v1/text-to-speech/compose:
    post:
      tags:
        - Text-to-Speech
      summary: 조합형 텍스트 음성 변환(Compose TTS)
      description: >-
        여러 음성 구간과 쉼을 하나의 오디오 파일로 생성합니다. `segments` 배열에 `tts`와 `pause` 객체를 재생할
        순서대로 넣으세요. 각 `tts` 세그먼트는 `POST /v1/text-to-speech`와 동일한 보이스, 모델, 감정, 출력
        설정을 지원하며 세그먼트마다 다른 보이스와 모델을 사용할 수 있습니다.


        **제한**

        - 전체 세그먼트는 최대 50개이며 `tts` 세그먼트가 최소 1개 필요합니다.

        - 모든 `tts` 세그먼트의 텍스트 합은 최대 2,000자입니다.

        - 쉼은 개별 최대 10초, 전체 합계 최대 60초입니다.

        - 모든 `tts` 세그먼트의 `audio_format`은 같아야 합니다.


        크레딧은 `tts` 텍스트 길이의 합만큼 차감되며 쉼에는 차감되지 않습니다. 세그먼트는 병렬로 합성된 뒤 입력 순서대로
        반환됩니다. 하나라도 합성에 실패하면 전체 요청이 실패하며 크레딧은 차감되지 않습니다.


        **응답**

        성공하면 JSON이 아닌 합성된 오디오 바이너리 데이터를 직접 반환합니다. 응답의 `Content-Type`은 세그먼트에서 요청한
        `audio_format`에 따라 `audio/wav` 또는 `audio/mpeg`입니다.
      operationId: text_to_speech_compose_v1_text_to_speech_compose_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ComposeRequest'
            example:
              segments:
                - type: tts
                  voice_id: tc_672c5f5ce59fac2a48faeaee
                  text: 안녕하세요. 오늘의 소식입니다.
                  model: ssfm-v30
                  language: kor
                  output:
                    audio_format: wav
                - type: pause
                  duration_seconds: 1.5
                - type: tts
                  voice_id: tc_66aca22c7d31e45ff05ff418
                  text: 첫 번째 소식을 전해드립니다.
                  model: ssfm-v30
                  language: kor
                  output:
                    audio_format: wav
        required: true
      responses:
        '200':
          description: 요청한 `audio_format`에 맞는 바이너리 합성 오디오 데이터
          content:
            audio/wav:
              schema:
                type: string
                format: binary
              example: '[Binary audio data - WAV file content]'
            audio/mpeg:
              schema:
                type: string
                format: binary
              example: '[Binary audio data - MP3 file content]'
        '401':
          description: 인증 실패
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                detail: Invalid API key
        '402':
          description: 전체 텍스트 길이에 비해 크레딧이 부족한 경우
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                detail: Insufficient credit
        '422':
          description: 세그먼트가 올바르지 않거나 Compose 제한을 초과한 경우
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                detail: Invalid request format
        '500':
          description: 하나 이상의 세그먼트 합성에 실패한 경우
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                detail: An unexpected error occurred
      x-codeSamples:
        - lang: cURL
          label: cURL (파일로 저장)
          source: |
            curl --request POST \
              --url https://api.typecast.ai/v1/text-to-speech/compose \
              --header 'Content-Type: application/json' \
              --header 'X-API-KEY: <api-key>' \
              --output output.wav \
              --data @- <<EOF
            {
              "segments": [
                {
                  "type": "tts",
                  "voice_id": "tc_672c5f5ce59fac2a48faeaee",
                  "text": "안녕하세요. 오늘의 소식입니다.",
                  "model": "ssfm-v30",
                  "language": "kor",
                  "output": { "audio_format": "wav" }
                },
                { "type": "pause", "duration_seconds": 1.5 },
                {
                  "type": "tts",
                  "voice_id": "tc_66aca22c7d31e45ff05ff418",
                  "text": "첫 번째 소식을 전해드립니다.",
                  "model": "ssfm-v30",
                  "language": "kor",
                  "output": { "audio_format": "wav" }
                }
              ]
            }
            EOF
        - lang: Python
          label: Python (requests)
          source: |
            import requests

            response = requests.post(
                "https://api.typecast.ai/v1/text-to-speech/compose",
                headers={"X-API-KEY": "<api-key>"},
                json={
                    "segments": [
                        {
                            "type": "tts",
                            "voice_id": "tc_672c5f5ce59fac2a48faeaee",
                            "text": "안녕하세요. 오늘의 소식입니다.",
                            "model": "ssfm-v30",
                            "language": "kor",
                            "output": {"audio_format": "wav"},
                        },
                        {"type": "pause", "duration_seconds": 1.5},
                        {
                            "type": "tts",
                            "voice_id": "tc_66aca22c7d31e45ff05ff418",
                            "text": "첫 번째 소식을 전해드립니다.",
                            "model": "ssfm-v30",
                            "language": "kor",
                            "output": {"audio_format": "wav"},
                        },
                    ]
                },
                timeout=120,
            )
            response.raise_for_status()
            with open("output.wav", "wb") as audio_file:
                audio_file.write(response.content)
components:
  schemas:
    ComposeRequest:
      type: object
      properties:
        segments:
          type: array
          items:
            oneOf:
              - $ref: '#/components/schemas/TTSComposeSegment'
              - $ref: '#/components/schemas/PauseComposeSegment'
            discriminator:
              propertyName: type
              mapping:
                pause:
                  $ref: '#/components/schemas/PauseComposeSegment'
                tts:
                  $ref: '#/components/schemas/TTSComposeSegment'
          title: Segments
          description: 출력 순서대로 나열한 음성과 쉼 세그먼트입니다. 최소 1개, 최대 50개이며 `tts` 세그먼트가 적어도 하나 필요합니다.
          minItems: 1
          maxItems: 50
      required:
        - segments
      title: ComposeRequest
      description: 음성과 쉼 세그먼트를 순서대로 합성하여 하나의 오디오 파일로 반환하는 요청입니다.
    ErrorResponse:
      type: object
      properties:
        detail:
          type: string
          description: 문제를 설명하는 오류 메시지
      required:
        - detail
      example:
        detail: An error occurred processing the request
    TTSComposeSegment:
      type: object
      properties:
        voice_id:
          type: string
          title: Voice Id
          description: 타입캐스트 기본 보이스(`tc_`) 또는 커스텀 보이스(`uc_`) 식별자입니다.
          example: tc_672c5f5ce59fac2a48faeaee
        text:
          type: string
          title: Text
          description: 합성할 텍스트입니다. 모든 `tts` 세그먼트의 텍스트 합은 최대 2,000자입니다.
          example: 안녕하세요. 오늘의 소식입니다.
          maxLength: 2000
          minLength: 1
        model:
          $ref: '#/components/schemas/TTSModel'
          description: 이 세그먼트에 사용할 음성 모델입니다. 세그먼트마다 다른 모델을 사용할 수 있습니다.
          example: ssfm-v30
        language:
          type: string
          title: Language
          description: ISO 639-3 언어 코드입니다. 생략하면 텍스트에서 언어를 감지합니다.
          example: kor
        prompt:
          title: Prompt
          description: 이 세그먼트의 감정과 문맥 설정입니다.
          oneOf:
            - $ref: '#/components/schemas/SmartPrompt'
            - $ref: '#/components/schemas/PresetPrompt'
            - $ref: '#/components/schemas/Prompt'
        output:
          $ref: '#/components/schemas/Output'
          description: 이 세그먼트의 오디오 설정입니다. 모든 세그먼트에서 같은 `audio_format`을 사용해야 합니다.
        seed:
          title: Seed
          description: 합성 결과 재현에 사용할 선택적 부호 없는 정수 시드입니다.
          example: 42
          anyOf:
            - type: integer
              maximum: 4294967295
              minimum: 0
            - type: 'null'
        type:
          type: string
          title: Type
          description: 세그먼트 구분값입니다. 항상 `tts`입니다.
          default: tts
          const: tts
      required:
        - type
        - voice_id
        - text
        - model
      title: TTSComposeSegment
      description: 일반 텍스트 음성 변환 요청과 동일한 합성 옵션을 사용하는 음성 세그먼트입니다.
      examples:
        - type: tts
          voice_id: tc_672c5f5ce59fac2a48faeaee
          text: 안녕하세요. 오늘의 소식입니다.
          model: ssfm-v30
          language: kor
          output:
            audio_format: wav
    PauseComposeSegment:
      type: object
      properties:
        type:
          type: string
          title: Type
          description: 세그먼트 구분값입니다. 항상 `pause`입니다.
          default: pause
          const: pause
        duration_seconds:
          type: number
          maximum: 10
          title: Duration Seconds
          description: 초 단위 쉼 길이입니다. 개별 쉼은 최대 10초, 모든 쉼의 합은 최대 60초입니다.
          example: 1.5
          exclusiveMinimum: 0
      required:
        - type
        - duration_seconds
      title: PauseComposeSegment
      description: 크레딧 차감 없이 삽입되는 무음 구간입니다.
      additionalProperties: false
      examples:
        - type: pause
          duration_seconds: 1.5
    TTSModel:
      type: string
      enum:
        - ssfm-v30
        - ssfm-v21
      title: TTSModel
      description: |
        음성 합성에 사용할 TTS 모델 버전. 다양한 모델은 다양한 기능과 품질 수준을 제공합니다.

        사용 가능한 모델:
        - **ssfm-v30**: 향상된 플로우와 추가 감정 프리셋이 있는 최신 모델(권장)
        - **ssfm-v21**: 검증된 신뢰성과 일관된 품질을 갖춘 안정적인 모델
    SmartPrompt:
      type: object
      properties:
        emotion_type:
          type: string
          title: Emotion Type
          description: |
            프롬프트 유형을 식별하는 판별자 필드. 컨텍스트 인식 감정 추론을 위해 "smart"로 설정해야 합니다.
          default: smart
          const: smart
        previous_text:
          type: string
          title: Previous Text
          description: |
            TTSRequest의 `text` 필드 이전에 오는 텍스트. 감정 추론을 위한 후방 컨텍스트를 제공합니다.

            모델은 흐름을 분석합니다: `previous_text` → `text`(합성됨) → `next_text`

            - 최대 2000자
            - 모델이 감정 빌드업과 컨텍스트를 이해하는 데 도움
            - 이전 컨텍스트가 없으면 비워 둡니다
          default: ''
          example: I feel like I'm walking on air and I just want to scream with joy!
        next_text:
          type: string
          title: Next Text
          description: |
            TTSRequest의 `text` 필드 이후에 오는 텍스트. 감정 추론을 위한 전방 컨텍스트를 제공합니다.

            모델은 흐름을 분석합니다: `previous_text` → `text`(합성됨) → `next_text`

            - 최대 2000자
            - 모델이 감정 전환을 예측하는 데 도움
            - 다음 컨텍스트가 없으면 비워 둡니다
          default: ''
          example: >-
            I am literally bursting with happiness and I never want this feeling
            to end!
      title: 스마트 프롬프트 (ssfm-v30)
      description: 생성된 음성의 감정 및 스타일 설정.
      example:
        emotion_type: smart
        previous_text: I feel like I'm walking on air and I just want to scream with joy!
        next_text: >-
          I am literally bursting with happiness and I never want this feeling
          to end!
      additionalProperties: false
    PresetPrompt:
      type: object
      properties:
        emotion_type:
          type: string
          title: Emotion Type
          description: |
            프롬프트 유형을 식별하는 판별자 필드. 프리셋 기반 감정 제어를 위해 "preset"으로 설정해야 합니다.
          default: preset
          const: preset
        emotion_preset:
          $ref: '#/components/schemas/EmotionEnum'
          description: |
            생성된 음성에 적용할 감정 프리셋.

            지원되는 감정: normal, happy, sad, angry, whisper, toneup, tonedown

            /v2/voices API를 통해 각 보이스에 사용 가능한 감정을 확인하세요.
          default: normal
          example: normal
        emotion_intensity:
          type: number
          maximum: 2
          minimum: 0
          title: Emotion Intensity
          description: |
            생성된 음성의 감정 표현 강도를 제어합니다.

            - 0.0: 완전히 중립적, 감정 색채 없음
            - 0.5: 미묘한 감정 힌트
            - 1.0: 표준 감정 표현(기본값)
            - 1.5: 강한 감정 강조
            - 2.0: 최대 강도, 매우 표현력 있음
          default: 1
          example: 1
      title: 프리셋 프롬프트 (ssfm-v30)
      description: 생성된 음성의 감정 및 스타일 설정.
      additionalProperties: false
    Prompt:
      properties:
        emotion_preset:
          description: |
            적용할 감정 프리셋.

            ssfm-v21 지원 감정: normal, happy, sad, angry

            /v2/voices API를 통해 각 보이스에 사용 가능한 감정을 확인하세요.
          example: normal
        emotion_intensity:
          description: |
            감정 표현 강도 제어(0.0~2.0).

            - 0.0: 완전히 중립적
            - 1.0: 표준 표현(기본값)
            - 2.0: 최대 강도
          example: 1
      title: 프롬프트 (ssfm-v21)
      description: 생성된 음성의 감정 및 스타일 설정.
    Output:
      type: object
      properties:
        target_lufs:
          type: integer
          title: Target Lufs
          description: >
            출력 음성의 목표 절대 음량(LUFS) 설정. 원본 음성의 크기와 상관없이 모든 음성을 일정한 크기로 정규화하여
            생성합니다. 값이 0에 가까울수록 소리가 커지며, -70에 가까울수록 작아집니다.


            - 필수 범위: -70 <= x <= 0

            - 권장값: -14 (일반적인 스트리밍 표준), -23 (방송 표준)

            - **주의:** `volume` 파라미터와 함께 사용할 수 없습니다. 절대적인 음량 기준이 필요할 때는
            `target_lufs`를, 상대적인 비율 조절이 필요할 때는 `volume`을 선택하여 사용하세요.
          example: -14
          anyOf:
            - type: number
              maximum: 0
              minimum: -70
            - type: 'null'
        volume:
          title: Volume
          description: >
            출력 음성의 상대적인 음량 조절: 0(완전 무음), 50(절반 볼륨), 100(표준 볼륨, 기본값), 150(표준보다
            50% 크게), 200(최대 볼륨, 표준의 두 배).


            출력된 음성마다 음량이 다를 경우, 단순 비율 조절인 `volume`을 사용하면 음성 간의 음량 편차가 더욱 커질 수
            있습니다. 일정한 음량 출력이 필요한 경우 `target_lufs` 사용을 권장합니다.


            - **주의:** `target_lufs`와 동시에 사용할 수 없습니다.


            필수 범위: 0 <= x <= 200
          example: 100
          anyOf:
            - type: integer
              maximum: 200
              minimum: 0
            - type: 'null'
        audio_pitch:
          type: integer
          maximum: 12
          minimum: -12
          title: Audio Pitch
          description: >-
            성별과 나이에 영향을 주는 반음 단위의 피치 조정: -12(한 옥타브 낮게, 더 깊은 목소리), -6(반 옥타브 낮게),
            0(원래 피치, 기본값), +6(반 옥타브 높게), +12(한 옥타브 높게, 더 높은 목소리)
          default: 0
          example: 0
        audio_tempo:
          type: number
          maximum: 2
          minimum: 0.5
          title: Audio Tempo
          description: >-
            음성 속도 제어: 0.5(절반 속도, 매우 느리고 명확함), 0.75(보통보다 약간 느림), 1.0(보통 말하기 속도,
            기본값), 1.5(보통보다 50% 빠름), 2.0(두 배 속도, 매우 빠른 음성)
          default: 1
          example: 1
        audio_format:
          type: string
          enum:
            - wav
            - mp3
          title: Audio Format
          description: |
            출력 오디오 형식.

            **WAV 형식:**
            - 비압축 PCM 오디오
            - 16비트 깊이, 모노 채널, 44100 Hz 샘플링 속도
            - 더 높은 품질, 더 큰 파일 크기
            - 전문 오디오 제작에 권장

            **MP3 형식:**
            - 압축된 MPEG Layer III 오디오
            - 320 kbps 비트레이트, 44100 Hz 샘플링 속도
            - 더 작은 파일 크기
            - 웹 스트리밍 및 배포에 권장
          default: wav
          example: wav
      title: Output
    EmotionEnum:
      type: string
      enum:
        - normal
        - sad
        - happy
        - angry
        - whisper
        - toneup
        - tonedown
      title: EmotionEnum
      description: |
        음성 합성에 사용 가능한 감정 프리셋. 각 감정은 생성된 음성의 톤, 속도, 표현력에 영향을 줍니다.

        **ssfm-v21 지원 감정 (4종류):**
        - normal: 중립적이고 균형 잡힌 톤
        - happy: 밝고 명랑한 표현
        - sad: 우울하고 차분한 톤
        - angry: 강하고 강렬한 전달

        **ssfm-v30 지원 감정 (7종류):**
        - normal: 중립적이고 균형 잡힌 톤
        - happy: 밝고 명랑한 표현
        - sad: 우울하고 차분한 톤
        - angry: 강하고 강렬한 전달
        - whisper: 부드럽고 조용한 말
        - toneup: 더 높은 톤 강조
        - tonedown: 더 낮은 톤 강조

        /v2/voices API 응답을 통해 각 음성에 사용 가능한 감정을 확인하세요.
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-KEY
      description: 인증을 위한 API 키. 타입캐스트 API 콘솔에서 API 키를 생성할 수 있습니다.

````