DeepScript

Integratie

REST API voor transcriptie – drie calls, klaar

Uploaden, pollen, resultaat ophalen. JSON, woord-timestamps, 99 talen, eigen servers in Duitsland.

De DeepScript API volgt het klassieke async job-patroon: je POST een audio- of videobestand naar `/v1/transcriptions`, krijgt een job-ID terug en pollt vervolgens om de paar seconden `/v1/transcriptions/{id}` of laat je via webhook informeren. Authenticatie verloopt via een `X-API-KEY`-header; sleutels beginnen met `ds_live_` en genereer je in het dashboard. De respons bevat de volledige tekst, woord-timestamps met confidence-scores, de gedetecteerde taal, sprekerlabels en de berekende kosten. Exportformaten (TXT, SRT, VTT, JSON) haal je op via `/v1/transcriptions/{id}/export?format=srt`. De volledige OpenAPI 3.1-spec staat op `/openapi.json`, een interactieve Scalar-UI op `/docs`.

OpenAPI 3.1-spec bekijken

Wat je kunt bouwen

  • Upload audio- en videobestanden tot 500 MB (mp3, wav, flac, ogg, m4a, aac, mp4, mkv, webm, mov).
  • Woordnauwkeurige timestamps met confidence per woord – perfect voor ondertitels en editor-integraties.
  • Sprekerdiarisatie in beide niveaus, DACH-dialectoptimalisatie in het Premium-model.
  • Custom Vocabulary per request – bedrijfsnamen, medische termen en eigennamen worden correct herkend.
  • Exportformaten op aanvraag: TXT, SRT, VTT, JSON. Geen her-encoding aan de clientzijde nodig.
  • Webhook-callbacks bij `transcription.completed` – pollen is optioneel, geen long-polling nodig.

Codevoorbeelden

Upload met curlcURL
# Upload an audio file and start a Premium transcription job
curl -X POST https://api.deepscript.com/v1/transcriptions \
  -H "X-API-KEY: ds_live_xxx" \
  -F "file=@meeting.mp3" \
  -F "model=premium" \
  -F "language=de"

# Response:
# {
#   "id": "8b1f2e4a-9c3d-4f7e-a1b2-1234567890ab",
#   "status": "queued",
#   "progress": 0,
#   "model": "premium",
#   "createdAt": "2026-06-09T10:14:22Z"
# }

# Poll until done
curl https://api.deepscript.com/v1/transcriptions/8b1f2e4a-9c3d-4f7e-a1b2-1234567890ab \
  -H "X-API-KEY: ds_live_xxx"

# Download as SRT
curl -o meeting.srt \
  "https://api.deepscript.com/v1/transcriptions/8b1f2e4a-9c3d-4f7e-a1b2-1234567890ab/export?format=srt" \
  -H "X-API-KEY: ds_live_xxx"
Node.js met fetchJavaScript
import { readFile } from "node:fs/promises";

const API_KEY = process.env.DEEPSCRIPT_API_KEY; // "ds_live_xxx"
const BASE = "https://api.deepscript.com/v1";

async function transcribe(filePath) {
  const buffer = await readFile(filePath);
  const blob = new Blob([buffer], { type: "audio/mpeg" });

  const form = new FormData();
  form.append("file", blob, "meeting.mp3");
  form.append("model", "premium");
  form.append("language", "de");

  const created = await fetch(`${BASE}/transcriptions`, {
    method: "POST",
    headers: { "X-API-KEY": API_KEY },
    body: form,
  }).then((r) => r.json());

  // Poll every 3 seconds until done
  while (true) {
    await new Promise((r) => setTimeout(r, 3000));
    const job = await fetch(`${BASE}/transcriptions/${created.id}`, {
      headers: { "X-API-KEY": API_KEY },
    }).then((r) => r.json());

    if (job.status === "completed") return job.result;
    if (job.status === "failed") throw new Error(job.errorMessage);
  }
}

const result = await transcribe("./meeting.mp3");
console.log(result.text);
Python met requestsPython
import os
import time
import requests

API_KEY = os.environ["DEEPSCRIPT_API_KEY"]  # "ds_live_xxx"
BASE = "https://api.deepscript.com/v1"
HEADERS = {"X-API-KEY": API_KEY}


def transcribe(path: str) -> dict:
    with open(path, "rb") as f:
        created = requests.post(
            f"{BASE}/transcriptions",
            headers=HEADERS,
            files={"file": f},
            data={"model": "premium", "language": "de"},
            timeout=120,
        ).json()

    job_id = created["id"]
    while True:
        time.sleep(3)
        job = requests.get(
            f"{BASE}/transcriptions/{job_id}", headers=HEADERS, timeout=30
        ).json()
        if job["status"] == "completed":
            return job["result"]
        if job["status"] == "failed":
            raise RuntimeError(job["errorMessage"])


result = transcribe("meeting.mp3")
print(result["text"])

Setup in een paar stappen

  1. 1

    Een API-sleutel genereren

    Genereer een sleutel in het dashboard onder Instellingen → Beveiliging. De sleutel wordt maar één keer getoond en begint met `ds_live_`. Sla hem op in je app als de omgevingsvariabele `DEEPSCRIPT_API_KEY`.

  2. 2

    De upload-request versturen

    Multipart-upload naar POST `/v1/transcriptions` met de velden `file`, `model` (standard/premium) en optioneel `language` (ISO 639-1) plus `vocabularyId`. Je krijgt direct een job-ID terug (HTTP 202).

  3. 3

    Pollen of op de webhook wachten

    Roep GET `/v1/transcriptions/{id}` elke 2-5 seconden aan, of registreer een webhook op `transcription.completed`. Vuistregel: 1 minuut audio = 5-15 seconden verwerking in Standard, iets langer in Premium.

  4. 4

    Het resultaat ophalen of exporteren

    Zodra `status: 'completed'`, bevat het veld `result` de volledige tekst, woorden met timestamps en sprekerlabels. Voor SRT/VTT/TXT/JSON-export: GET `/v1/transcriptions/{id}/export?format=srt`.

Veelgestelde vragen

Wat zijn de rate limits?

100 requests per minuut per API-sleutel bij geauthenticeerde calls, 30/min zonder authenticatie. De respons bevat de headers `X-RateLimit-Limit`, `X-RateLimit-Remaining` en `X-RateLimit-Reset`. Bij overschrijding krijg je HTTP 429 met een Retry-After-header.

Ondersteunen jullie idempotency keys?

Ja – stuur `Idempotency-Key: <uuid>` als header bij POST `/v1/transcriptions`. Identieke sleutels binnen 24 uur geven dezelfde respons terug zonder de job een tweede keer te starten. Aanbevolen voor retries bij netwerkproblemen.

Welk poll-interval kun je het beste gebruiken?

We raden 2-5 seconden aan. Voor langere audio (>30 min) is elke 10 seconden prima. Wil je liever niet pollen, gebruik dan webhooks (`/v1/webhooks`) of de Server-Sent Events-stream op `/v1/transcriptions/{id}/events`.

Wat gebeurt er bij een mislukte job?

De status wisselt naar `failed` en het veld `errorMessage` bevat een RFC 7807-conforme Problem Details-string. Veelvoorkomende oorzaken: bestand te kort (<1 s), geen detecteerbare audio, niet-ondersteund formaat. Voor mislukte jobs worden geen kosten in rekening gebracht.

Is er een officiële SDK?

Voorlopig leveren we de OpenAPI 3.1-spec op `/openapi.json` – gebruik `openapi-generator-cli` of `openapi-typescript` om een getypeerde client in elke taal te genereren. Officiële SDK's voor TypeScript en Python zijn in de maak.

Klaar om dit naar productie te brengen?

Maak een account aan, genereer een API-sleutel en ga van start. Drie transcripties gratis om te testen. Volledige OpenAPI 3.1-docs op api.deepscript.com/docs.

DeepScript REST API – Speech-to-Text uit Duitsland | DeepScript