v1.0.0

API Reference

Integrate Morlivo translation and transcription into your application with a few lines of code.

Base URL: https://api.morlivo.ai Auth: Authorization: Bearer mrl_...

Authentication

All API requests require a Bearer token. Get your API key from the dashboard under Settings.

Header
Authorization: Bearer mrl_your_api_key_here

API keys start with mrl_. Keep them secret. Rotate them from the dashboard if compromised.

POST

/v1/translate

Translate text from one language to another. Source language is auto-detected if omitted.

Request body JSON

FieldTypeRequiredDescription
textstringyesText to translate
target_languagestringyesISO 639-1 code (e.g. es, fr, de)
source_languagestringnoAuto-detected if omitted
project_idintegernoApply project glossary and style
formalitystringnoRegister: formal, informal, or default

Response 200

FieldTypeDescription
translated_textstringThe translated text
source_languagestringDetected or provided source language
target_languagestringTarget language code
confidencefloatQuality score 0.0 - 1.0
validationobjectQuality validation results

Examples

curl
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"
  }'
Python
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!"
JavaScript
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!"
Response
{
  "translated_text": "¡Hola, mundo!",
  "source_language": "en",
  "target_language": "es",
  "confidence": 0.98,
  "validation": {
    "length_ratio": 1.08,
    "language_match": true,
    "passed": true
  }
}
POST

/v1/transcribe

Transcribe an audio or video file to text. Supports up to 100 MB.

Request body multipart/form-data

FieldTypeRequiredDescription
filefileyesAudio/video file (mp3, wav, mp4, webm, etc.)
languagestringnoISO code, auto-detected if omitted
project_idintegernoLink to a project for tracking
response_formatstringnoOutput format: json, verbose_json, text, srt, vtt
punctuatebooleannoInclude punctuation (default true)

Response 200

FieldTypeDescription
textstringFull transcribed text
languagestringDetected language
duration_secondsfloatAudio duration
confidencefloatQuality score 0.0 - 1.0
language_confidencefloatConfidence of auto-detected language (null if language was specified)
segmentsarrayTimestamped segments
validationobjectQuality checks

Examples

curl
curl -X POST https://api.morlivo.ai/api/v1/transcribe \
  -H "Authorization: Bearer mrl_your_key" \
  -F "file=@meeting.mp3" \
  -F "language=en"
Python
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"])
Response
{
  "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
  }
}
WebSocket

/v1/live/transcribe

Stream audio in real-time and receive live transcription results.

Connection

ParameterTypeRequiredDescription
tokenstringyesAPI key as query parameter
languagestringnoSource language hint (e.g. en, fr). Auto-detected if omitted.

Protocol

Send

Binary PCM audio frames (16-bit, 16kHz mono)

Receive

JSON messages with type field: transcript (partial/final text), status (session events), error

Messages received

FieldTypeDescription
typestring"transcript" | "status" | "error"
textstringTranscribed text (on transcript messages)
is_finalbooleanTrue when segment is complete
languagestringDetected language code

Examples

JavaScript
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);
  }
};
Python
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())
Message examples
// 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}
WebSocket

/v1/live/translate

Stream audio in one language and receive translated text in another language in real-time. Supports speech-to-text translation with automatic language detection.

Connection

ParameterTypeRequiredDescription
tokenstringyesAPI key as query parameter
target_languagestringyesLanguage for output text (e.g. en, es, fr)
source_languagestringnoSource audio language. Auto-detected if omitted.

Protocol

Send

Binary PCM audio frames (16-bit, 16kHz mono)

Receive

JSON messages with translated text in target_language. Includes both transcript of original speech and translated output.

Messages received

FieldTypeDescription
typestring"transcript" | "status" | "error"
textstringTranslated text in target language
is_finalbooleanTrue when segment is complete
source_languagestringDetected source language
target_languagestringTarget language code

Examples

JavaScript
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);
  }
};
Python
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())
Message examples
// 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}
POST

/v1/live/rooms

Create a multi-participant translation room. Each participant speaks their own language and receives translated text from other participants.

Request body JSON

FieldTypeRequiredDescription
languagesobjectyesParticipant ID to language mapping
bridge_languagestringnoHub language, default en
max_participantsintnoMax participants 2-10, default 10
modestringnointerpreter or inline

Response 200

FieldTypeDescription
room_idstringUnique room identifier
statusstringRoom status
languagesobjectParticipant ID to language mapping
bridge_languagestringHub language used for translation
modestringTranslation mode
max_participantsintMaximum number of participants

Examples

curl
curl -X POST https://api.morlivo.ai/api/v1/live/rooms \
  -H "Authorization: Bearer mrl_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "languages": {"alice": "en", "bob": "fr", "carlos": "es"},
    "bridge_language": "en",
    "mode": "interpreter"
  }'
Response
{
  "room_id": "room_abc123",
  "status": "active",
  "languages": {"alice": "en", "bob": "fr", "carlos": "es"},
  "bridge_language": "en",
  "mode": "interpreter",
  "max_participants": 10
}
WebSocket

/v1/live/speech/{room_id}

Connect a participant to a room for real-time speech translation.

Connection

ParameterTypeRequiredDescription
room_idstringyesRoom ID from create room response (path param)
participantstringyesParticipant ID (query param)
tokenstringyesAPI key as query parameter

Example

JavaScript
const ws = new WebSocket(
  "wss://live.morlivo.ai/v1/live/speech/room_abc123" +
  "?token=mrl_your_key&participant=alice"
);

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);
  }
};
POST

/v1/live/rooms/{room_id}/participants

Add a participant to an existing room after creation.

Request body JSON

FieldTypeRequiredDescription
participant_idstringyesUnique participant identifier
languagestringyesParticipant's language code

Example

curl
curl -X POST https://api.morlivo.ai/api/v1/live/rooms/room_abc123/participants \
  -H "Authorization: Bearer mrl_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "participant_id": "diana",
    "language": "de"
  }'
GET

/v1/languages

List all supported languages with locale, name, and availability status.

Response 200

FieldTypeDescription
languagesarrayList of supported languages
languages[].localestringLocale code e.g. fr-CA
languages[].namestringEnglish name
languages[].native_namestringNative name
languages[].countrystringCountry/region
languages[].statusstringga or beta

Example

curl
curl https://api.morlivo.ai/api/v1/languages \
  -H "Authorization: Bearer mrl_your_key"
Response
{
  "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"}
  ]
}
GET

/v1/health

Check API status and database health. No authentication required.

Response 200

FieldTypeDescription
statusstringhealthy or degraded

Example

curl
curl https://api.morlivo.ai/api/v1/health
Response
{
  "status": "healthy"
}

Compatibility Endpoints

Already using another provider? Change one URL and keep your existing code. These endpoints mirror the request and response formats of major translation and transcription APIs.

DL

DeepL

Translation
POST /api/compat/deepl/v2/translate

Drop-in replacement for api-free.deepl.com

G

Google Cloud Translation

Translation
POST /api/compat/google/v3/projects/{"{p}"}/locations/{"{l}"}:translateText

Drop-in replacement for translation.googleapis.com

A

AWS Translate

Translation
POST /api/compat/aws/translate

Drop-in replacement for translate.amazonaws.com

OA

OpenAI Whisper

Transcription
POST /api/compat/openai/v1/audio/transcriptions

Drop-in replacement for api.openai.com

DG

Deepgram

Transcription
POST /api/compat/deepgram/v1/listen

Drop-in replacement for api.deepgram.com

Compatibility endpoints accept the same request format and return the same response structure as the original provider. Refer to each provider's documentation for their request/response schemas.

Errors

All errors return a JSON object with a detail field.

CodeMeaningWhen it happens
400 Bad Request Missing required fields, empty text, unsupported file type
401 Unauthorized Missing or invalid API key
403 Forbidden API key valid but insufficient permissions or quota exceeded
413 Payload Too Large File exceeds 100 MB upload limit
429 Rate Limited Too many requests. Retry with exponential backoff.
500 Internal Error Unexpected server error. Contact support if it persists.
503 Service Unavailable AI model temporarily unavailable (circuit breaker open). Retry shortly.
Error response format
{
  "detail": "Field 'text' must not be empty."
}
POST

PII Redaction

Add PII redaction to any translation or transcription request. Specify which entity types to detect and redact.

POST /v1/translate POST /v1/transcribe

Request body JSON

FieldTypeRequiredDescription
textstringyesText to translate
source_languagestringnoAuto-detected if omitted
target_languagestringyesISO 639-1 code (e.g. es, fr, de)
redactstring[]noEntity types to redact (e.g. email, phone, name)

Response 200

FieldTypeDescription
translated_textstringTranslated text with PII redacted
source_languagestringDetected or provided source language
target_languagestringTarget language code
confidencefloatQuality score 0.0 - 1.0
redactionsarrayList of redactions applied (type and replacement)

Examples

curl
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"]
  }'
Python
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]"
JavaScript
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]"
Response
{
  "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]"}
  ]
}

Supported Entity Types

EntityDescriptionDetection
email Email addresses Pattern-based (included)
phone Phone numbers Pattern-based (included)
ssn Social Security numbers Pattern-based (included)
credit_card Credit card numbers Pattern-based (included)
ip_address IP addresses Pattern-based (included)
name Person names AI-powered (additional cost)
address Physical addresses AI-powered (additional cost)
medical Medical information AI-powered (additional cost)

Format-based entities (email, phone, SSN, credit card, IP) are detected using pattern matching at no additional cost. Contextual entities (name, address, medical) use AI-powered detection and incur a small additional charge per request.

Ready to integrate?

Create a free account to get your API key and start translating.