DeepScript

Intégration

API REST de transcription – trois appels, c'est fait

Uploadez, faites du polling, récupérez le résultat. JSON, horodatages par mot, 99 langues, serveurs propres en Allemagne.

L'API DeepScript suit le schéma classique du job asynchrone : vous envoyez en POST un fichier audio ou vidéo vers `/v1/transcriptions`, vous recevez un ID de job, puis vous faites du polling sur `/v1/transcriptions/{id}` toutes les quelques secondes ou vous vous faites notifier par webhook. L'authentification passe par un en-tête `X-API-KEY` ; les clés commencent par `ds_live_` et se génèrent dans le tableau de bord. La réponse contient le texte intégral, les horodatages par mot avec scores de confiance, la langue détectée, les labels de locuteurs et le coût calculé. Les formats d'export (TXT, SRT, VTT, JSON) sont disponibles via `/v1/transcriptions/{id}/export?format=srt`. La spécification OpenAPI 3.1 complète se trouve sur `/openapi.json`, une interface Scalar interactive sur `/docs`.

Voir la spécification OpenAPI 3.1

Ce que vous pouvez créer

  • Uploadez des fichiers audio et vidéo jusqu'à 500 Mo (mp3, wav, flac, ogg, m4a, aac, mp4, mkv, webm, mov).
  • Horodatages précis au mot avec score de confiance par mot – parfait pour les sous-titres et les intégrations d'éditeur.
  • Diarisation des locuteurs dans les deux formules, optimisation des dialectes DACH dans le modèle Premium.
  • Custom Vocabulary par requête – noms d'entreprises, termes médicaux et noms propres sont correctement reconnus.
  • Formats d'export à la demande : TXT, SRT, VTT, JSON. Aucun ré-encodage côté client requis.
  • Callbacks webhook sur `transcription.completed` – le polling est optionnel, pas de long-polling requis.

Exemples de code

Upload avec 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 avec 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 avec 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"])

Configuration en quelques étapes

  1. 1

    Générer une clé API

    Générez une clé dans le tableau de bord sous Paramètres → Sécurité. La clé ne s'affiche qu'une seule fois et commence par `ds_live_`. Stockez-la dans votre application en tant que variable d'environnement `DEEPSCRIPT_API_KEY`.

  2. 2

    Envoyer la requête d'upload

    Upload multipart vers POST `/v1/transcriptions` avec les champs `file`, `model` (standard/premium) et, en option, `language` (ISO 639-1) ainsi que `vocabularyId`. Vous recevez immédiatement un ID de job (HTTP 202).

  3. 3

    Faire du polling ou attendre le webhook

    Appelez GET `/v1/transcriptions/{id}` toutes les 2 à 5 secondes, ou enregistrez un webhook sur `transcription.completed`. Règle générale : 1 minute d'audio = 5 à 15 secondes de traitement en Standard, un peu plus en Premium.

  4. 4

    Récupérer ou exporter le résultat

    Lorsque `status: 'completed'`, le champ `result` contient le texte intégral, les mots avec horodatages et les labels de locuteurs. Pour l'export SRT/VTT/TXT/JSON : GET `/v1/transcriptions/{id}/export?format=srt`.

Questions fréquentes

Quelles sont les limites de débit ?

100 requêtes par minute et par clé API pour les appels authentifiés, 30/min sans authentification. La réponse inclut les en-têtes `X-RateLimit-Limit`, `X-RateLimit-Remaining` et `X-RateLimit-Reset`. En cas de dépassement, vous recevez un HTTP 429 avec un en-tête Retry-After.

Prenez-vous en charge les clés d'idempotence ?

Oui – envoyez `Idempotency-Key: <uuid>` en en-tête sur POST `/v1/transcriptions`. Des clés identiques dans un délai de 24 heures renvoient la même réponse sans relancer le job. Recommandé pour les retries en cas de problèmes réseau.

Quel intervalle de polling utiliser ?

Nous recommandons 2 à 5 secondes. Pour les audios plus longs (>30 min), toutes les 10 secondes suffisent. Si vous préférez éviter le polling, utilisez les webhooks (`/v1/webhooks`) ou le flux Server-Sent Events sur `/v1/transcriptions/{id}/events`.

Que se passe-t-il en cas de job échoué ?

Le statut passe à `failed` et le champ `errorMessage` contient une chaîne Problem Details conforme à la RFC 7807. Causes fréquentes : fichier trop court (<1 s), aucun audio détectable, format non pris en charge. Les jobs échoués ne vous sont pas facturés.

Existe-t-il un SDK officiel ?

Pour l'instant, nous fournissons la spécification OpenAPI 3.1 sur `/openapi.json` – utilisez `openapi-generator-cli` ou `openapi-typescript` pour générer un client typé dans n'importe quel langage. Des SDK officiels pour TypeScript et Python sont en préparation.

Prêt à mettre ça en production ?

Créez un compte, générez une clé API, c'est parti. Trois transcriptions gratuites pour tester. Documentation OpenAPI 3.1 complète sur api.deepscript.com/docs.

API REST DeepScript – Speech-to-Text depuis l'Allemagne | DeepScript