Pronunciation API Documentation

Integrate pronunciation scoring into your application with our REST API

Authentication

Authenticate your requests using an API key in the Authorization header:

Authorization: Bearer lx_your_api_key_here

⚠️ Keep your API key secure: Never expose your API key in client-side code or public repositories.

Endpoint Details

🔬 Syllable-Level Precision

The V3 API delivers the deepest pronunciation analysis available: every word is broken down to individual syllables with IPA transcription, pitch class and millisecond timing, across 17 languages.

POST/api/pronunciation/v3/check

Syllable-level pronunciation analysis with 17-language support

✨ Operating Modes:

  • Known text mode: Provide sentence parameter → Scores pronunciation syllable-by-syllable against expected text
  • Just Talk mode: Omit sentence parameter → Whisper AI transcribes your speech first, then scores pronunciation

Request Parameters

ParameterTypeRequiredDescription
speechdatafileYesAudio file (WAV, MP3, M4A, OGG, FLAC, WEBM). Max 10 MiB.
sentencestringNoExpected text to compare against. If omitted, Whisper transcribes speech first ("Just Talk" mode).
language_codestringNoLanguage code (default: ja). One of the 17 codes listed below.

💡 Send compressed audio

Encode client-side to MP3, Opus/WebM or AAC before uploading. A 10-second utterance is roughly 320 KB as 16 kHz mono WAV but under 40 KB as 64 kbps Opus — the same score, a fraction of the upload time. Uploads over 10 MiB are rejected with status code 413.

V3 Code Example

lingolix (PyPI) · @lingolix/sdk (npm)

you should set the API key as an environment variable:

export LINGOLIX_API_KEY=your_api_key_here

# pip install lingolix  (or: uv add lingolix)
from lingolix import Lingolix, QuotaExceededError

# WARNING: Keep API keys server-side only! Never expose in client-side code.
# Lingolix() reads $LINGOLIX_API_KEY. AsyncLingolix is the async twin.
with Lingolix() as client:
    try:
        # Known text mode
        r = client.check("audio.wav", sentence="Guten Morgen", language="de")

        # Just Talk mode (sentence omitted)
        # r = client.check("audio.wav", language="de")

        print(r.accuracy, r.completeness, r.speaking_rate)
        for word in r.words:
            for s in word.syllables:
                print(s.text, s.expected_ipa, "→", s.detected_ipa, s.pitch, round(s.accuracy, 2))
    except QuotaExceededError as e:
        print(f"{e.plan} plan is out of minutes — upgrade at {e.upgrade_url}")

Response Format

Each word contains a syllables array with per-syllable IPA and timing. speaking_rate is measured in subwords (syllables) per second.

{
  "text": "Guten Morgen",
  "speaking_rate": 12.5,
  "accuracy": 0.7777777910232544,
  "completeness": 1,
  "words": [
    {
      "text": "Guten",
      "syllables": [
        {
          "text": "Gu",
          "expected_ipa": "ɡuː",
          "detected_ipa": "ɡu",
          "accuracy": 1,
          "completeness": 1,
          "pitch": "low",
          "duration_ms": 60,
          "start_ms": 20,
          "end_ms": 40,
          "is_missing": false,
          "is_extra": false
        },
        {
          "text": "ten",
          "expected_ipa": "tn̩",
          "detected_ipa": "tn",
          "accuracy": 1,
          "completeness": 1,
          "pitch": "high",
          "duration_ms": 100,
          "start_ms": 70,
          "end_ms": 110,
          "is_missing": false,
          "is_extra": false
        }
      ],
      "accuracy": 1,
      "completeness": 1,
      "start_ms": 20,
      "end_ms": 110,
      "char_start": 0,
      "char_end": 5
    },
    {
      "text": "Morgen",
      "syllables": [
        {
          "text": "Mor",
          "expected_ipa": "mɔʁ",
          "detected_ipa": "ma",
          "accuracy": 0.3333333134651184,
          "completeness": 0.6666666666666667,
          "pitch": "high",
          "duration_ms": 60,
          "start_ms": 160,
          "end_ms": 180,
          "is_missing": false,
          "is_extra": false
        },
        {
          "text": "gen",
          "expected_ipa": "ɡn̩",
          "detected_ipa": "ɡn",
          "accuracy": 1,
          "completeness": 1,
          "pitch": "flat",
          "duration_ms": 100,
          "start_ms": 220,
          "end_ms": 260,
          "is_missing": false,
          "is_extra": false
        }
      ],
      "accuracy": 0.6000000238418579,
      "completeness": 0.5,
      "start_ms": 160,
      "end_ms": 260,
      "char_start": 6,
      "char_end": 12
    }
  ]
}

Word Fields

FieldDescription
textWord text
accuracyMean accuracy across the word's syllables (0.0 – 1.0)
completenessFraction of the word's syllables detected
start_msStart offset in milliseconds
end_msEnd offset in milliseconds
char_startCharacter index of this word in the response's text field. -1 for Japanese and for extra words the user said that weren't in the expected text
char_endCharacter index (exclusive) where this word ends in the response's text field. -1 under the same conditions as char_start

Syllable Fields

FieldDescription
textSyllable text (e.g. "ni")
expected_ipaExpected IPA transcription
detected_ipaDetected IPA from audio
accuracyPhoneme-level accuracy (0.0 – 1.0)
completenessFraction of expected phonemes detected
pitchPitch class: high | low | flat | unknown
duration_msSyllable duration in milliseconds
start_msStart offset in milliseconds
end_msEnd offset in milliseconds
is_missingtrue if the user skipped this syllable
is_extratrue if the user said something not in target

Supported Languages (17 total)

LanguageCode
🇯🇵 Japaneseja
🇬🇧 Englishen
🇩🇪 Germande
🇫🇷 Frenchfr
🇪🇸 Spanishes
🇭🇺 Hungarianhu
🇧🇬 Bulgarianbg
🇨🇿 Czechcs
🇬🇷 Greekel
🇫🇮 Finnishfi
🇮🇹 Italianit
🇰🇷 Koreanko
🇳🇱 Dutchnl
🇵🇱 Polishpl
🇵🇹 Portuguesept
🇸🇪 Swedishsv
🇺🇦 Ukrainianuk
💡 Numbers, dates and currency amounts are expanded automatically for English, German, French and Spanish. Other languages score them as written.

Rate Limits & Quotas

Quota System

Your monthly quota is measured in audio minutes and is shared across all your API keys. Check your current usage in the Dashboard.

Free Tier

  • 15 minutes per month
  • Hard limit - requests blocked when quota exhausted
  • Returns 429 error when quota exceeded

Paid Tiers

  • Higher monthly quotas (180 min – 13,200 min depending on plan)
  • Overage allowed with per-minute billing
  • Overage rates: €0.02 - €0.05 per minute depending on plan

💡 Tip: Monitor your usage regularly to avoid unexpected charges. Upgrade your plan in the Subscription page.

Error Handling

Status CodeErrorSolution
401Invalid or missing API keyCheck your Authorization header
400Invalid audio formatUse WAV, MP3, M4A, OGG, FLAC, or WEBM format
413Audio file too largeKeep uploads under 10 MiB; encode to MP3/Opus instead of WAV
429Quota exceededUpgrade plan or wait for next billing period
503Service unavailableRetry after a short delay

Need Help?

Have questions or need support integrating the API? We're here to help!

Contact Support