Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.supertoneapi.com/llms.txt

Use this file to discover all available pages before exploring further.

이 문서는 영어 원문을 기반으로 자동 번역되었습니다. 표현이 어색하거나 모호한 부분이 있을 수 있으니, 정확한 내용은 영어 원문을 함께 확인해 주세요.
공식 TypeScript SDK는 npm에 @supertone/supertone으로 공개되어 있습니다. 소스: supertone-inc/supertone-ts.

설치

npm add @supertone/supertone
이 패키지는 ESMCommonJS 진입점을 모두 제공하며 TypeScript 타입을 포함합니다. Node 18+가 필요합니다(전역 fetchReadableStream을 위해). Bun과 Deno에서도 동작하며, 브라우저용으로는 설계되지 않았습니다(API Key는 절대 클라이언트 측에 두면 안 됩니다).

API Key 설정

export SUPERTONE_API_KEY="Kp9mZ3xQ7v..."
import { Supertone } from "@supertone/supertone";

const client = new Supertone({ apiKey: process.env.SUPERTONE_API_KEY });
보이스 ID는 환경 변수로 다루지 않습니다 — 사용 사례마다 달라지므로, 코드에 일반 문자열로 두거나(또는 요청 페이로드에서 전달하세요).

음성 생성하기

import { Supertone } from "@supertone/supertone";
import * as fs from "node:fs";

const VOICE_ID = "20160a4c5ba38967330c84"; // replace with your voice ID

const client = new Supertone({ apiKey: process.env.SUPERTONE_API_KEY });

const response = await client.textToSpeech.createSpeech({
  voiceId: VOICE_ID,
  apiConvertTextToSpeechUsingCharacterRequest: {
    text: "Hello from the TypeScript SDK.",
    language: "en",
    model: "sona_speech_1",
    outputFormat: "wav",
  },
});

if (response.result instanceof Uint8Array) {
  fs.writeFileSync("speech.wav", response.result);
} else if (response.result && "getReader" in response.result) {
  const reader = (response.result as ReadableStream<Uint8Array>).getReader();
  const chunks: Uint8Array[] = [];
  while (true) {
    const { done, value } = await reader.read();
    if (done) break;
    if (value) chunks.push(value);
  }
  fs.writeFileSync("speech.wav", Buffer.concat(chunks));
}
모든 메서드는 비동기이며 Promise를 반환합니다. 동기 대안은 제공되지 않습니다.

음성 스트리밍

import { Supertone } from "@supertone/supertone";
import * as fs from "node:fs";

const VOICE_ID = "20160a4c5ba38967330c84"; // replace with your voice ID

const client = new Supertone({ apiKey: process.env.SUPERTONE_API_KEY });

const response = await client.textToSpeech.streamSpeech({
  voiceId: VOICE_ID,
  apiConvertTextToSpeechUsingCharacterRequest: {
    text: "This response is streamed chunk by chunk.",
    language: "en",
    model: "sona_speech_1",
  },
});

if (response.result && typeof response.result === "object" && "getReader" in response.result) {
  const reader = (response.result as ReadableStream<Uint8Array>).getReader();
  const chunks: Uint8Array[] = [];
  while (true) {
    const { done, value } = await reader.read();
    if (done) break;
    if (value) chunks.push(value);
  }
  fs.writeFileSync("streamed.wav", Buffer.concat(chunks));
}
스트리밍은 현재 sona_speech_1에서만 지원됩니다.

긴 텍스트 자동 청크 분할

createSpeechstreamSpeech 모두 300자보다 긴 텍스트를 자동으로 청크 분할합니다. 텍스트를 그대로 전달하면 SDK가 분할하고, 각 세그먼트를 생성한 뒤 결과를 병합(또는 스트리밍)합니다.
const response = await client.textToSpeech.createSpeech(
  {
    voiceId: VOICE_ID,
    apiConvertTextToSpeechUsingCharacterRequest: { text: longText, language: "en" },
  },
  {
    maxTextLength: 300, // optional override (default 300)
  },
);
predictDuration은 자동 청크 분할을 수행하지 않습니다 — 300자 제한이 그대로 적용됩니다. 자세한 내용은 긴 텍스트를 참고하세요.

자주 사용하는 작업

// List voices with pagination
const list = await client.voices.listVoices({ pageSize: 20 });

// Search voices
const search = await client.voices.searchVoices({
  language: "ko,en",
  style: "happy",
});

// Get a single voice
const voice = await client.voices.getVoice({ voiceId: VOICE_ID });

// Predict duration (no credits deducted)
const { duration } = await client.textToSpeech.predictDuration({
  voiceId: VOICE_ID,
  predictTTSDurationRequest: {
    text: "How long will this be?",
    language: "en",
  },
});

// Get credit balance
const balance = await client.usage.getCreditBalance();

타입 안전 enum(선택)

타입 안전성을 위해 SDK는 @supertone/supertone/models에 enum 상수를 노출합니다.
import * as models from "@supertone/supertone/models";

models.APIConvertTextToSpeechUsingCharacterRequestLanguage.En;     // "en"
models.APIConvertTextToSpeechUsingCharacterRequestModel.SonaSpeech1; // "sona_speech_1"
일반 문자열 리터럴("en", "sona_speech_1")도 동일하게 동작합니다 — 선호하는 방식을 선택하세요.

오류 처리

오류는 @supertone/supertone/models/errors에 있으며 모두 SupertoneError를 상속합니다.
import { Supertone } from "@supertone/supertone";
import * as errors from "@supertone/supertone/models/errors";

const client = new Supertone({ apiKey: process.env.SUPERTONE_API_KEY });

try {
  const response = await client.textToSpeech.createSpeech({ /* ... */ });
} catch (err) {
  if (err instanceof errors.TooManyRequestsErrorResponse) {
    console.log("Rate limited:", err.message);
  } else if (err instanceof errors.UnauthorizedErrorResponse) {
    console.log("Auth failed:", err.message);
  } else if (err instanceof errors.PaymentRequiredErrorResponse) {
    console.log("Out of credits:", err.message);
  } else if (err instanceof errors.SupertoneError) {
    console.log(`HTTP ${err.statusCode}: ${err.message}`);
  } else {
    throw err;
  }
}
Error classHTTP status
BadRequestErrorResponse400
UnauthorizedErrorResponse401
PaymentRequiredErrorResponse402
ForbiddenErrorResponse403
NotFoundErrorResponse404
RequestTimeoutErrorResponse408
PayloadTooLargeErrorResponse413
UnsupportedMediaTypeErrorResponse415
TooManyRequestsErrorResponse429
InternalServerErrorResponse500
네트워크 계층 오류(ConnectionError, RequestTimeoutError, RequestAbortedError 등)는 SupertoneError가 아닌 HTTPClientError를 상속합니다.

설정

const client = new Supertone({
  apiKey: process.env.SUPERTONE_API_KEY,
  timeoutMs: 30_000,
  retryConfig: {
    strategy: "backoff",
    backoff: { initialInterval: 500, maxInterval: 60_000, exponent: 1.5, maxElapsedTime: 3_600_000 },
    retryConnectionErrors: true,
  },
});

관련 문서

Python SDK

Python을 위한 동등한 SDK입니다.

예제

자주 사용하는 워크플로에 대한 레시피입니다.