Devniks Voice API

Yiddish-first speech-to-text and text-to-speech over plain HTTPS and JSON. Free, with daily limits per key.

Base URL https://voice.devniks.com

Quick start

  1. Create an account and accept the Terms.
  2. Create a key on the API keys page.
  3. Send your first file:
curl https://voice.devniks.com/v1/asr \
  -H "Authorization: Bearer $DEVNIKS_API_KEY" \
  -F file=@shiur.mp3 \
  -F language=yi \
  -F wait=true

Authentication

Send your key in the Authorization header on every request. Keys start with dv_live_. Keep them on your server, never in a public page or app. If a key leaks, revoke it on the API keys page and create a new one.

Authorization: Bearer dv_live_xxxxxxxxxxxxxxxxxxxx

Transcribe audio

POST/v1/asr

Upload audio as multipart/form-data. Short files (under 60 s) can wait for the result with wait=true; longer files return 202 with a job id: poll GET /v1/asr/{id} or use a webhook.

FieldTypeDescription
filefile, requiredMP3, WAV, M4A, OGG, FLAC, MP4. Max 500 MB / 2 hours.
languagestringyi, he, en or auto (default).
timestampsstringsegment (default) or word.
waitbooleanHold the connection until done (files under 60 s). Default false.
webhook_urlstringOptional. We POST asr.completed here.

Response

{
  "id": "asr_01HF8Q3K2Z",
  "status": "done",
  "language": "yi",
  "duration": 42.3,
  "model": "devniks-asr-2.3",
  "text": "שלום עליכם, דאס איז א מעלדונג פון די שול. ...",
  "segments": [
    { "id": 0, "start": 0.0, "end": 4.2, "confidence": 0.97,
      "text": "שלום עליכם, דאס איז א מעלדונג פון די שול." },
    { "id": 1, "start": 4.2, "end": 8.9, "confidence": 0.81,
      "text": "מנחה וועט היינט זיין פינף מינוט פאר שקיעה." }
  ],
  "created_at": "2026-10-27T13:12:04Z"
}

Get a transcript

GET/v1/asr/{id}

Returns the same object. status is queued, processing, done or failed. Add ?format=srt, vtt or txt to get subtitles or plain text instead of JSON.

Submit a correction

PATCH/v1/asr/{id}

Send corrected text for one or more segments (or the full text). We keep the original model output next to your correction. Corrections earn the same free credits as on the web: +1 minute per corrected audio minute, after a spot check.

curl -X PATCH https://voice.devniks.com/v1/asr/asr_01HF8Q3K2Z \
  -H "Authorization: Bearer $DEVNIKS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"segments": [{"id": 2, "text": "נאך מעריב איז דא א שיעור אין גמרא בבא מציעא."}]}' 

Response

{
  "id": "asr_01HF8Q3K2Z",
  "corrected_segments": 1,
  "credit": { "minutes": 0.1, "status": "pending_review" }
}

Generate speech

POST/v1/tts
FieldTypeDescription
textstring, requiredUp to 5,000 characters. Yiddish, Hebrew or English.
voicestring, requiredA voice id from GET /v1/voices.
formatstringmp3 (default) or wav (24 kHz).
speednumber0.6 to 1.6. Default 1.0.
pitchinteger-6 to 6 semitones. Default 0.

Returns the audio file. The X-Devniks-Request-Id header is the id to rate it with POST /v1/tts/{id}/rating ({"good": false, "words": [3], "issue_type": "pronunciation"}). If generation takes longer than 60 s you get 202 with a JSON job instead: poll GET /v1/tts/{id} and download from GET /v1/tts/{id}/audio.

curl https://voice.devniks.com/v1/tts \
  -H "Authorization: Bearer $DEVNIKS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text": "ברוכים הבאים צו דעווניקס.", "voice": "shmuel", "format": "mp3"}' \
  --output welcome.mp3

List voices

GET/v1/voices
{
  "voices": [
    { "id": "shmuel", "name": "Shmuel", "style": "warm",     "languages": ["yi", "he", "en"] },
    { "id": "dovid",  "name": "Dovid",  "style": "narrator", "languages": ["yi", "he", "en"] },
    { "id": "kol",    "name": "Kol",    "style": "neutral",  "languages": ["yi", "he", "en"] },
    { "id": "vc_7Hk2", "name": "My voice", "style": "cloned", "private": true }
  ]
}

Cloned voices are created in the web app (with the speaker-consent step) and are visible only to your account.

Rate limits (free tier)

LimitFree tier, per key
Requests60 per minute
ASR audio120 minutes per day
TTS text50,000 characters per day
Concurrent ASR jobs2
Keys per account5

Every response carries X-RateLimit-Remaining and X-RateLimit-Reset. GET /v1/usage returns what is left today for the key. Need more for a community project? Write to us; corrections you send back also raise your limits.

Errors

HTTPcodeMeaning
400invalid_requestA field is missing or wrong.
401unauthorizedMissing, wrong or revoked key.
403consent_requiredThe account hasn't accepted the current Terms.
404not_foundNo such transcript or voice on your account.
413file_too_largeOver 500 MB or 2 hours.
415unsupported_mediaWe couldn't read the audio.
429rate_limited / quota_exceededToo many requests, or the daily limit is used up.
500 / 503server_error / model_busyOur side. Safe to retry with backoff.
{
  "error": {
    "code": "quota_exceeded",
    "message": "Daily free ASR limit reached (120 min). Resets 00:00 UTC.",
    "request_id": "req_9kd2Lq"
  }
}

Webhooks (optional)

Pass webhook_url (HTTPS) with an ASR job and we POST asr.completed or asr.failed to it when the job finishes. Check the signature with your webhook secret (shown on the API keys page) and reply 2xx within 10 s; we retry up to 5 times. The same event can arrive twice, so dedupe on delivery_id.

POST https://your-app.example.com/hooks/devniks
X-Devniks-Event: asr.completed
X-Devniks-Delivery: evt_01jb8q3k2z...
X-Devniks-Signature: t=1761570724,v1=5f2b9c...   (HMAC-SHA256 of "t.body" with your webhook secret)

{ "event": "asr.completed", "delivery_id": "evt_01jb8q3k2z...", "id": "asr_01HF8Q3K2Z", "status": "done" }

Verify in Python: hmac.compare_digest(v1, hmac.new(secret.encode(), f"{t}.{raw_body}".encode(), "sha256").hexdigest()), and reject timestamps older than 5 minutes.

Your data

Audio, text and corrections sent through the API are stored under the same Terms & Privacy as the web app: kept private, used by Devniks only to improve and retrain its speech models, never sold or published. Delete any item with DELETE /v1/asr/{id}, or everything from Settings.