DocumentationImports de fichiers

Imports de fichiers

Envoyez jusqu'à 95 Mo en une seule requête. Pour les fichiers jusqu'à 2 Go, utilisez un envoi par blocs que vous pouvez reprendre en cas de coupure.

Pour transcrire un fichier audio ou vidéo, importez-le dans l'API. Les fichiers passent toujours par la transcription par IA : seules les valeurs auto et stt sont acceptées pour source. Vous pouvez aussi régler language et diarize, comme expliqué dans Sources et options.

Formats et tailles acceptés

Vérifiez l'extension du fichier avant de l'envoyer. Elle doit être dans cette liste : mp3, wav, m4a, flac, ogg, opus, mp4, mov, webm, mkv. Sinon, l'API répond 422 unsupported_media. Le fichier doit aussi contenir une piste audio. Sans elle, la transcription échoue avec unsupported_media.

LimiteValeur
Envoi en une seule requête (multipart/form-data)95 Mo
Envoi par blocs2 Go (2 000 000 000 octets), ou moins selon votre offre.
Imports par blocs ouverts en même temps par équipe20

Si le fichier dépasse la taille autorisée, l'API répond 413 media_too_large. Le champ max_bytes de l'erreur vous donne la limite applicable.

Envoyer le fichier en une seule requête

Jusqu'à 95 Mo, appelez POST /v1/transcriptions en multipart/form-data avec le fichier dans le champ file. Vous pouvez ajouter les champs de formulaire language, diarize (true ou false), source (auto ou stt) et webhook_url. Tous sont facultatifs.

curl -X POST "https://api.transcript1.com/v1/transcriptions?wait=60" \
  -H "Authorization: Bearer $TRANSCRIPT1_API_KEY" \
  -F [email protected] \
  -F language=en \
  -F diarize=true

Vous recevez un objet transcription avec source.platform à upload. Comme pour un lien vidéo, le statut HTTP vaut 202 si le traitement continue et 200 s'il a atteint un état final. Si vous envoyez un fichier vide, l'API répond 422 invalid_request.

Envoyer un gros fichier en plusieurs blocs

Pour les gros fichiers, découpez l'envoi en blocs. En cas de coupure, vous n'aurez pas à tout recommencer. L'import se déroule en quatre étapes.

1. Réserver l'import

Commencez par envoyer le nom et la taille du fichier en JSON. Vous pouvez préciser mime_type, mais ce n'est pas obligatoire. Ajoutez l'en-tête Idempotency-Key pour pouvoir répéter cet appel sans créer une seconde transcription :

curl -X POST "https://api.transcript1.com/v1/transcriptions" \
  -H "Authorization: Bearer $TRANSCRIPT1_API_KEY" \
  -H "Idempotency-Key: interview-2026-10-13" \
  -H "Content-Type: application/json" \
  -d '{"upload":{"filename":"interview.m4a","size":48210334,"mime_type":"audio/mp4"},"language":"auto","diarize":true}'

L'API répond 201. La transcription porte le statut awaiting_upload, et le bloc upload contient les instructions d'envoi :

{
  "id": "tr_8fK2Lm0PqRsTuVwXyZaBcD",
  "object": "transcription",
  "status": "awaiting_upload",
  "upload": {
    "chunk_url_template": "https://api.transcript1.com/v1/transcriptions/tr_8fK2Lm0PqRsTuVwXyZaBcD/upload/chunks/{index}",
    "headers": { "X-Upload-Token": "t1u_..." },
    "expires_at": "2026-10-13T10:30:00.000Z",
    "chunks": [
      { "index": 0, "offset": 0, "size": 8388608 },
      { "index": 1, "offset": 8388608, "size": 8388608 }
    ]
  }
}

Le serveur définit les blocs à envoyer, d'environ 8 Mio chacun (8 388 608 octets). Leur liste figure dans chunks ; l'exemple ci-dessus est abrégé. Gardez X-Upload-Token secret : ce token ne sert qu'à cet import et expire au bout de 1 heure, à la date indiquée par expires_at.

2. Envoyer les blocs

Pour chaque bloc, construisez l'URL à partir de chunk_url_template : remplacez {index} par son index, puis envoyez une requête PUT à cette adresse. Lisez size octets dans le fichier à partir de offset et placez-les dans le corps de la requête, en application/octet-stream. La taille doit correspondre exactement à celle prévue par le serveur.

Pour cet appel, transmettez le token dans X-Upload-Token. Vous n'avez pas besoin de l'en-tête Authorization.

curl -X PUT "https://api.transcript1.com/v1/transcriptions/tr_8fK2Lm0PqRsTuVwXyZaBcD/upload/chunks/0" \
  -H "X-Upload-Token: t1u_..." \
  -H "Content-Type: application/octet-stream" \
  --data-binary @chunk-0.bin

Après chaque bloc, l'API renvoie { "object": "upload_chunk", "index": 0, "size": 8388608 }. Si vous renvoyez le même bloc, il remplace le précédent. Une taille incorrecte ou un index absent de la liste prévue donne 422 invalid_request. Un token manquant ou expiré donne 401 unauthorized.

3. Reprendre un envoi interrompu

Appelez GET /v1/transcriptions/:id/upload pour savoir quels blocs le serveur a reçus :

{
  "object": "upload",
  "status": "awaiting_upload",
  "total_bytes": 48210334,
  "uploaded_bytes": 16777216,
  "received_chunks": [0, 1],
  "chunks": [ { "index": 0, "offset": 0, "size": 8388608 } ],
  "expires_at": "2026-10-13T10:30:00.000Z"
}

Reprenez l'envoi avec les seuls blocs absents de received_chunks. Si le token a expiré, refaites l'appel de l'étape 1 avec la même Idempotency-Key et les mêmes paramètres. Vous retrouverez la même transcription, avec un nouveau token pour poursuivre l'import.

4. Valider l'envoi

curl -X POST "https://api.transcript1.com/v1/transcriptions/tr_8fK2Lm0PqRsTuVwXyZaBcD/upload/complete" \
  -H "Authorization: Bearer $TRANSCRIPT1_API_KEY"

L'appel à POST /v1/transcriptions/:id/upload/complete vérifie la présence et la taille de tous les blocs, reconstitue le fichier et met la transcription en file d'attente. Vous recevez alors 202 avec l'objet transcription.

S'il manque des blocs, l'API répond 409 upload_incomplete. Le champ missing_chunks indique leurs index : envoyez ces blocs, puis validez à nouveau. Si l'import est déjà terminé ou annulé, vous recevez 409 invalid_state.

Une fois l'envoi validé, suivez le traitement avec GET /v1/transcriptions/:id?wait=60 ou un webhook.

Tout l'envoi en Python

import os
import requests
 
API = "https://api.transcript1.com"
auth = {"Authorization": f"Bearer {os.environ['TRANSCRIPT1_API_KEY']}"}
path = "interview.m4a"
 
created = requests.post(
    f"{API}/v1/transcriptions",
    headers={**auth, "Idempotency-Key": "interview-2026-10-13"},
    json={"upload": {"filename": os.path.basename(path), "size": os.path.getsize(path)}},
)
created.raise_for_status()
transcription = created.json()
upload = transcription["upload"]
 
with open(path, "rb") as file:
    for chunk in upload["chunks"]:
        file.seek(chunk["offset"])
        url = upload["chunk_url_template"].replace("{index}", str(chunk["index"]))
        response = requests.put(
            url,
            data=file.read(chunk["size"]),
            headers={**upload["headers"], "Content-Type": "application/octet-stream"},
        )
        response.raise_for_status()
 
done = requests.post(f"{API}/v1/transcriptions/{transcription['id']}/upload/complete", headers=auth)
done.raise_for_status()
print(done.json()["status"])

Limites et suppression des fichiers

  • Votre équipe peut avoir 20 imports ouverts à la fois, au statut awaiting_upload. Au-delà, la création renvoie 429 too_many_active_jobs avec un en-tête Retry-After.
  • Vous avez 24 heures après la création pour terminer l'import. Passé ce délai, il est annulé et les blocs sont supprimés.
  • Le fichier audio ou vidéo est supprimé 24 heures après le passage à un état final : completed, failed ou canceled. Le texte reste disponible jusqu'à sa suppression avec DELETE /v1/transcriptions/:id.
  • Si la transcription échoue ou si vous l'annulez, vous ne payez rien. Le décompte se fait dès que la durée du fichier est connue, par minute de média arrondie au supérieur. Consultez Facturation et limites.

Dernière mise à jour 14 octobre 2026