API 레퍼런스
몇 줄의 코드로 Morlivo 번역 및 전사를 애플리케이션에 통합하세요.
https://api.morlivo.ai
인증: Authorization: Bearer mrl_...
인증
모든 API 요청은 Bearer 토큰이 필요합니다. 대시보드의 설정에서 API 키를 확인하세요.
Authorization: Bearer mrl_your_api_key_here
API 키는 다음으로 시작합니다 mrl_. 비밀로 유지하세요. 유출된 경우 대시보드에서 교체하세요.
/v1/translate
텍스트를 한 언어에서 다른 언어로 번역합니다. 소스 언어는 생략하면 자동으로 감지됩니다.
요청 본문 JSON
| 필드 | 입력 | 필수 | 설명 |
|---|---|---|---|
text | string | 예 | 번역할 텍스트 |
target_language | string | 예 | ISO 639-1 코드 (예: es, fr, de) |
source_language | string | 아니요 | 생략하면 자동 감지됨 |
project_id | integer | 아니요 | 프로젝트 용어집 및 스타일 적용 |
formality | string | 아니요 | 문체: 격식체, 비격식체 또는 기본 |
응답 200
| 필드 | 입력 | 설명 |
|---|---|---|
translated_text | string | 번역된 텍스트 |
source_language | string | 감지되었거나 제공된 소스 언어 |
target_language | string | 대상 언어 코드 |
confidence | float | 품질 점수 0.0 - 1.0 |
validation | object | 품질 검증 결과 |
예시
curl -X POST https://api.morlivo.ai/api/v1/translate \
-H "Authorization: Bearer mrl_your_key" \
-H "Content-Type: application/json" \
-d '{
"text": "Hello, world!",
"target_language": "es"
}'
import httpx
resp = httpx.post(
"https://api.morlivo.ai/api/v1/translate",
headers={"Authorization": "Bearer mrl_your_key"},
json={
"text": "Hello, world!",
"target_language": "es",
},
)
data = resp.json()
print(data["translated_text"])
# → "¡Hola, mundo!"
const resp = await fetch(
"https://api.morlivo.ai/api/v1/translate",
{
method: "POST",
headers: {
"Authorization": "Bearer mrl_your_key",
"Content-Type": "application/json",
},
body: JSON.stringify({
text: "Hello, world!",
target_language: "es",
}),
}
);
const data = await resp.json();
console.log(data.translated_text);
// → "¡Hola, mundo!"
{
"translated_text": "¡Hola, mundo!",
"source_language": "en",
"target_language": "es",
"confidence": 0.98,
"validation": {
"length_ratio": 1.08,
"language_match": true,
"passed": true
}
}
/v1/transcribe
오디오 또는 비디오 파일을 텍스트로 전사합니다. 최대 100 MB까지 지원합니다.
요청 본문 multipart/form-data
| 필드 | 입력 | 필수 | 설명 |
|---|---|---|---|
file | file | 예 | 오디오/비디오 파일 (mp3, wav, mp4, webm 등) |
language | string | 아니요 | ISO 코드, 생략하면 자동 감지됨 |
project_id | integer | 아니요 | 추적을 위해 프로젝트와 연결 |
response_format | string | 아니요 | 출력 형식: json, verbose_json, text, srt, vtt |
punctuate | boolean | 아니요 | 구두점 포함 (기본값 true) |
응답 200
| 필드 | 입력 | 설명 |
|---|---|---|
text | string | 전체 전사 텍스트 |
language | string | 감지된 언어 |
duration_seconds | float | 오디오 길이 |
confidence | float | 품질 점수 0.0 - 1.0 |
language_confidence | float | 자동 감지된 언어에 대한 신뢰도 (언어가 지정된 경우 null) |
segments | array | 타임스탬프가 있는 세그먼트 |
validation | object | 품질 검사 |
예시
curl -X POST https://api.morlivo.ai/api/v1/transcribe \
-H "Authorization: Bearer mrl_your_key" \
-F "file=@meeting.mp3" \
-F "language=en"
import httpx
with open("meeting.mp3", "rb") as f:
resp = httpx.post(
"https://api.morlivo.ai/api/v1/transcribe",
headers={"Authorization": "Bearer mrl_your_key"},
files={"file": ("meeting.mp3", f, "audio/mpeg")},
data={"language": "en"},
)
data = resp.json()
print(data["text"])
{
"text": "Welcome everyone to today's meeting...",
"language": "en",
"duration_seconds": 342.5,
"confidence": 0.95,
"language_confidence": 0.95,
"segments": [
{"start": 0.0, "end": 3.2, "text": "Welcome everyone"},
{"start": 3.2, "end": 6.8, "text": "to today's meeting."}
],
"validation": {
"words_per_minute": 148,
"repetition_detected": false,
"passed": true
}
}
/v1/live/transcribe
오디오를 실시간으로 스트리밍하고 라이브 전사 결과를 받아보세요.
연결
| 매개변수 | 입력 | 필수 | 설명 |
|---|---|---|---|
token | string | 예 | 쿼리 매개변수로 전달된 API 키 |
language | string | 아니요 | 원본 언어 힌트(예: en, fr). 생략하면 자동 감지됩니다. |
프로토콜
이진 PCM 오디오 프레임 (16비트, 16kHz 모노)
type 필드를 포함한 JSON 메시지: transcript (부분/최종 텍스트), status (세션 이벤트), error
받은 메시지
| 필드 | 입력 | 설명 |
|---|---|---|
type | string | "transcript" | "status" | "error" |
text | string | 전사된 텍스트(전사 메시지에 표시됨) |
is_final | boolean | 세그먼트가 완료되면 True |
language | string | 감지된 언어 코드 |
예시
const ws = new WebSocket(
"wss://live.morlivo.ai/v1/live/transcribe?token=mrl_your_key&language=en"
);
navigator.mediaDevices.getUserMedia({ audio: true })
.then(stream => {
const ctx = new AudioContext({ sampleRate: 16000 });
const source = ctx.createMediaStreamSource(stream);
const processor = ctx.createScriptProcessor(4096, 1, 1);
source.connect(processor);
processor.connect(ctx.destination);
processor.onaudioprocess = (e) => {
const pcm = e.inputBuffer.getChannelData(0);
const int16 = new Int16Array(pcm.length);
for (let i = 0; i < pcm.length; i++)
int16[i] = Math.max(-1, Math.min(1, pcm[i])) * 0x7FFF;
ws.send(int16.buffer);
};
});
ws.onmessage = (event) => {
const msg = JSON.parse(event.data);
if (msg.type === "transcript") {
console.log(msg.is_final ? "FINAL:" : "partial:", msg.text);
}
};
import asyncio, json, websockets
async def live_transcribe():
uri = "wss://live.morlivo.ai/v1/live/transcribe?token=mrl_your_key"
async with websockets.connect(uri) as ws:
# Send audio chunks (PCM 16-bit 16kHz mono)
with open("audio.pcm", "rb") as f:
while chunk := f.read(4096):
await ws.send(chunk)
msg = json.loads(await ws.recv())
if msg["type"] == "transcript":
print(msg["text"], end="\r" if not msg["is_final"] else "\n")
asyncio.run(live_transcribe())
// Session started
{"type": "status", "message": "session_started"}
// Partial transcript (still speaking)
{"type": "transcript", "text": "Hello every", "is_final": false}
// Final transcript (segment complete)
{"type": "transcript", "text": "Hello everyone, welcome to the meeting.",
"is_final": true, "language": "en"}
// Session ended
{"type": "status", "message": "session_ended",
"duration_seconds": 45.2}
/v1/live/translate
한 언어로 오디오를 스트리밍하고 다른 언어로 번역된 텍스트를 실시간으로 받아보세요. 자동 언어 감지 기능을 갖춘 음성-텍스트 번역을 지원합니다.
연결
| 매개변수 | 입력 | 필수 | 설명 |
|---|---|---|---|
token | string | 예 | 쿼리 매개변수로 전달된 API 키 |
target_language | string | 예 | 출력 텍스트 언어(예: en, es, fr) |
source_language | string | 아니요 | 원본 오디오 언어. 생략하면 자동 감지됩니다. |
프로토콜
이진 PCM 오디오 프레임 (16비트, 16kHz 모노)
target_language에 번역된 텍스트가 포함된 JSON 메시지. 원래 음성의 전사와 번역 결과 모두 포함합니다.
받은 메시지
| 필드 | 입력 | 설명 |
|---|---|---|
type | string | "transcript" | "status" | "error" |
text | string | 대상 언어로 번역된 텍스트 |
is_final | boolean | 세그먼트가 완료되면 True |
source_language | string | 감지된 소스 언어 |
target_language | string | 대상 언어 코드 |
예시
const ws = new WebSocket(
"wss://live.morlivo.ai/v1/live/translate" +
"?token=mrl_your_key&target_language=es&source_language=en"
);
// Stream microphone audio (same setup as live transcribe)
// ...
ws.onmessage = (event) => {
const msg = JSON.parse(event.data);
if (msg.type === "transcript" && msg.is_final) {
console.log(`[${msg.source_language} → ${msg.target_language}]`);
console.log(msg.text);
}
};
import asyncio, json, websockets
async def live_translate():
uri = (
"wss://live.morlivo.ai/v1/live/translate"
"?token=mrl_your_key"
"&source_language=fr&target_language=en"
)
async with websockets.connect(uri) as ws:
with open("french_audio.pcm", "rb") as f:
while chunk := f.read(4096):
await ws.send(chunk)
msg = json.loads(await ws.recv())
if msg["type"] == "transcript" and msg["is_final"]:
print(f"Translation: {msg['text']}")
asyncio.run(live_translate())
// Partial translation
{"type": "transcript", "text": "Hello every",
"is_final": false, "source_language": "fr", "target_language": "en"}
// Final translated segment
{"type": "transcript",
"text": "Hello everyone, welcome to the meeting.",
"is_final": true,
"source_language": "fr", "target_language": "en"}
// Session summary
{"type": "status", "message": "session_ended",
"duration_seconds": 120.5}
/v1/languages
지원되는 모든 언어를 로케일, 이름 및 사용 가능 상태와 함께 나열하세요.
응답 200
| 필드 | 입력 | 설명 |
|---|---|---|
languages | array | 지원되는 언어 목록 |
languages[].locale | string | 로케일 코드 예: fr-CA |
languages[].name | string | 영문 이름 |
languages[].native_name | string | 원어 이름 |
languages[].country | string | 국가/지역 |
languages[].status | string | GA 또는 베타 |
예시
curl https://api.morlivo.ai/api/v1/languages \
-H "Authorization: Bearer mrl_your_key"
{
"languages": [
{"locale": "en-US", "name": "English", "native_name": "English", "country": "United States", "status": "ga"},
{"locale": "fr-CA", "name": "French", "native_name": "Français", "country": "Canada", "status": "ga"},
{"locale": "sw-KE", "name": "Swahili", "native_name": "Kiswahili", "country": "Kenya", "status": "beta"}
]
}
/v1/health
API 상태 및 데이터베이스 상태를 확인하세요. 인증이 필요하지 않습니다.
응답 200
| 필드 | 입력 | 설명 |
|---|---|---|
status | string | 정상 또는 저하 |
예시
curl https://api.morlivo.ai/api/v1/health
{
"status": "healthy"
}
호환성 엔드포인트
다른 공급자를 이미 사용 중이신가요? URL 하나만 변경하고 기존 코드를 유지하세요. 이 엔드포인트는 주요 번역 및 전사 API의 요청 및 응답 형식을 그대로 반영합니다.
DeepL
번역POST /api/compat/deepl/v2/translate
Drop-in 대체 api-free.deepl.com
Google Cloud Translation
번역POST /api/compat/google/v3/projects/{p}/locations/{l}:translateText
Drop-in 대체 translation.googleapis.com
AWS Translate
번역POST /api/compat/aws/translate
Drop-in 대체 translate.amazonaws.com
OpenAI Whisper
전사POST /api/compat/openai/v1/audio/transcriptions
Drop-in 대체 api.openai.com
Deepgram
전사POST /api/compat/deepgram/v1/listen
Drop-in 대체 api.deepgram.com
호환성 엔드포인트는 원래 제공자와 동일한 요청 형식을 수락하고 동일한 응답 구조를 반환합니다. 요청/응답 스키마는 각 제공자의 문서를 참조하세요.
오류
모든 오류는 detail 필드를 가진 JSON 객체를 반환합니다.
| 코드 | 의미 | 발생했을 때 |
|---|---|---|
| 400 | 잘못된 요청 | 필수 필드 누락, 빈 텍스트, 지원되지 않는 파일 형식 |
| 401 | 권한 없음 | API 키 누락 또는 유효하지 않음 |
| 403 | 금지됨 | API 키는 유효하지만 필요한 범위 또는 테넌트 권한이 없습니다 |
| 402 | 결제 필요 | 신용이 부족하거나 카드 인증이 필요합니다. 가능한 경우 응답에 billing_url 및 X-Credits-* 헤더가 포함됩니다. |
| 413 | 페이로드가 너무 큽니다 | 파일이 100 MB 업로드 제한을 초과합니다. |
| 429 | 속도 제한됨 | 요청이 너무 많습니다. 지수 백오프를 사용하여 재시도하세요. |
| 500 | 내부 오류 | 예기치 않은 서버 오류입니다. 계속 발생하면 지원팀에 문의하세요. |
| 503 | 서비스 이용 불가 | AI 모델을 일시적으로 사용할 수 없습니다(회로 차단기 열림). 잠시 후 다시 시도하세요. |
{
"detail": "Field 'text' must not be empty."
}
{
"error": "insufficient_credits",
"detail": "Insufficient credits",
"billing_url": "/app/billing"
}
성공적인 API 응답에는 X-Credits-Spent 및 X-Credits-Remaining 헤더가 포함됩니다. 크레딧이 소진되면 클라이언트는 재시도를 중단하고 사용자를 billing_url로 이동시켜야 합니다.
PII 가리기
모든 번역 또는 전사 요청에 개인 식별 정보(PII) 마스킹을 추가하세요. 감지하고 마스킹할 엔터티 유형을 지정하세요.
요청 본문 JSON
| 필드 | 입력 | 필수 | 설명 |
|---|---|---|---|
text | string | 예 | 번역할 텍스트 |
source_language | string | 아니요 | 생략하면 자동 감지됨 |
target_language | string | 예 | ISO 639-1 코드 (예: es, fr, de) |
redact | string[] | 아니요 | 가림 처리할 엔터티 유형(예: 이메일, 전화번호, 이름) |
응답 200
| 필드 | 입력 | 설명 |
|---|---|---|
translated_text | string | 개인 식별 정보(PII)가 가려진 번역 텍스트 |
source_language | string | 감지되었거나 제공된 소스 언어 |
target_language | string | 대상 언어 코드 |
confidence | float | 품질 점수 0.0 - 1.0 |
redactions | array | 적용된 편집 목록(유형 및 대체) |
예시
curl -X POST https://api.morlivo.ai/api/v1/translate \
-H "Authorization: Bearer mrl_your_key" \
-H "Content-Type: application/json" \
-d '{
"text": "Contact John Smith at john@example.com or 555-123-4567",
"source_language": "en",
"target_language": "fr",
"redact": ["email", "phone", "name"]
}'
import httpx
resp = httpx.post(
"https://api.morlivo.ai/api/v1/translate",
headers={"Authorization": "Bearer mrl_your_key"},
json={
"text": "Contact John Smith at john@example.com or 555-123-4567",
"source_language": "en",
"target_language": "fr",
"redact": ["email", "phone", "name"],
},
)
data = resp.json()
print(data["translated_text"])
# → "Contactez [NAME_REDACTED] à [EMAIL_REDACTED] ou [PHONE_REDACTED]"
const resp = await fetch(
"https://api.morlivo.ai/api/v1/translate",
{
method: "POST",
headers: {
"Authorization": "Bearer mrl_your_key",
"Content-Type": "application/json",
},
body: JSON.stringify({
text: "Contact John Smith at john@example.com or 555-123-4567",
source_language: "en",
target_language: "fr",
redact: ["email", "phone", "name"],
}),
}
);
const data = await resp.json();
console.log(data.translated_text);
// → "Contactez [NAME_REDACTED] à [EMAIL_REDACTED] ou [PHONE_REDACTED]"
{
"translated_text": "Contactez [NAME_REDACTED] à [EMAIL_REDACTED] ou [PHONE_REDACTED]",
"source_language": "en",
"target_language": "fr",
"confidence": 0.95,
"redactions": [
{"type": "name", "replacement": "[NAME_REDACTED]"},
{"type": "email", "replacement": "[EMAIL_REDACTED]"},
{"type": "phone", "replacement": "[PHONE_REDACTED]"}
]
}
지원되는 엔터티 유형
| 엔터티 | 설명 | 감지 |
|---|---|---|
email |
이메일 주소 | 패턴 기반(포함됨) |
phone |
전화번호 | 패턴 기반(포함됨) |
ssn |
사회보장번호 | 패턴 기반(포함됨) |
credit_card |
신용카드 번호 | 패턴 기반(포함됨) |
ip_address |
IP 주소 | 패턴 기반(포함됨) |
name |
사람 이름 | AI 기반(추가 비용 발생) |
address |
실제 주소 | AI 기반(추가 비용 발생) |
medical |
의료 정보 | AI 기반(추가 비용 발생) |
형식 기반 개체(이메일, 전화번호, SSN, 신용카드, IP)는 패턴 매칭으로 추가 비용 없이 감지됩니다. 문맥 기반 개체(이름, 주소, 의료 정보)는 AI 기반 감지를 사용하며 요청당 소액의 추가 요금이 발생합니다.