# 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.

Canonical: https://transcript1.com/fr/docs/uploads
Language: fr
Last updated: 2026-10-14

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](https://transcript1.com/fr/docs/sources-and-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`.

| Limite | Valeur |
|---|---|
| Envoi en une seule requête (`multipart/form-data`) | 95 Mo |
| Envoi par blocs | 2 Go (2 000 000 000 octets), ou moins selon votre offre. |
| Imports par blocs ouverts en même temps par équipe | 20 |

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.

```bash
curl -X POST "https://api.transcript1.com/v1/transcriptions?wait=60" \
  -H "Authorization: Bearer $TRANSCRIPT1_API_KEY" \
  -F file=@interview.m4a \
  -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 :

```bash
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 :

```json
{
  "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`.

```bash
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 :

```json
{
  "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

```bash
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](https://transcript1.com/fr/docs/webhooks).

### Tout l'envoi en Python

```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](https://transcript1.com/fr/docs/billing-and-limits).
