# Fouten afhandelen

> Herken fouten aan hun code, lees het foutobject en bepaal wanneer je een request opnieuw kunt sturen.

Canonical: https://transcript1.com/nl/docs/errors
Language: nl
Last updated: 2026-10-19

Een request kan meteen worden geweigerd. Een transcriptie kan ook pas later mislukken, nadat de API die al heeft geaccepteerd. In dat geval staat `status` op `failed`. Houd deze twee situaties uit elkaar bij het afhandelen van fouten.

## Zo ziet een foutresponse eruit

Als een `/v1`-request mislukt, krijg je dit vaste formaat:

```json
{
  "error": {
    "code": "insufficient_minutes",
    "message": "Not enough minutes",
    "retryable": false,
    "action_url": "https://transcript1.com/dashboard/billing",
    "minutes_needed": 20,
    "minutes_remaining": 3
  }
}
```

Laat je code reageren op `code`, niet op de tekst van `message`. Die tekst is voor de gebruiker en kan veranderen. Staat `retryable` op `true`, dan kan hetzelfde request later wel slagen.

Afhankelijk van de fout krijg je naast `retryable` extra velden:

| Veld | Foutcode | Wat staat erin? |
|---|---|---|
| `action_url` | `insufficient_minutes` | De link om een abonnement te nemen of minuten bij te kopen. |
| `minutes_needed`, `minutes_remaining` | `insufficient_minutes` | Het aantal benodigde minuten en je huidige saldo. Het benodigde aantal is `null` zolang de duur nog onbekend is. |
| `supported_platforms` | `unsupported_platform` | De toegestane platforms: `["youtube", "x", "tiktok", "instagram", "facebook", "bluesky", "twitch", "dailymotion", "pinterest", "linkedin", "snapchat"]`. |
| `missing_chunks` | `upload_incomplete` | De indexen van de chunks die de server nog mist. |
| `max_bytes` | `media_too_large` | Jouw maximale bestandsgrootte in bytes. |
| `params` | `invalid_request` | Bij ongeldige body- of queryvelden een object dat per veld uitlegt wat je moet aanpassen. |

## Wanneer de API je request weigert

| HTTP-status | `code` | Opnieuw proberen? | Oorzaak |
|---|---|---|---|
| 400, 422 | `invalid_request` | Nee | Een parameter of bodyveld ontbreekt of is ongeldig. Dit geldt ook voor ongeldige JSON en combinaties zoals `diarize` met `source: "captions"` of `reuse_recent` met `webhook_url`. |
| 422 | `invalid_url` | Nee | De link is niet geldig of komt niet overeen met `platform`. Gebruik YouTube, X, TikTok, Instagram, Facebook, Bluesky of een ander platform uit [Bronnen en instellingen](https://transcript1.com/nl/docs/sources-and-options). |
| 422 | `unsupported_platform` | Nee | De opgegeven waarde voor `platform` is niet toegestaan. |
| 422 | `unsupported_media` | Nee | De bestandsextensie wordt niet ondersteund. |
| 401 | `unauthorized` | Nee | Je API-sleutel of token ontbreekt, is ongeldig, verlopen of ingetrokken. Ook een ongeldig of verlopen uploadtoken geeft deze fout. |
| 403 | `insufficient_scope` | Nee | Het OAuth-token heeft geen `transcriptions:read` of `transcriptions:write` waar die scope nodig is. |
| 403 | `email_not_verified` | Nee | Je moet eerst je e-mailadres bevestigen om transcripties te kunnen starten. |
| 402 | `insufficient_minutes` | Nee | Je beschikbare saldo is 0 of je hebt te weinig minuten voor deze transcriptie. |
| 402 | `no_active_plan` | Nee | Je wilt minuten bijkopen, maar hebt geen actief betaald abonnement. Alleen het billing-endpoint van het dashboard geeft deze fout, niet de transcriptie-endpoints. |
| 404 | `not_found` | Nee | De transcriptie bestaat niet of is van een ander team. |
| 409 | `upload_incomplete` | Nee | De server mist nog chunks. Verstuur die en rond de upload daarna opnieuw af. |
| 409 | `invalid_state` | Nee | De transcriptie wacht niet meer op een upload. Je kunt geen chunks meer sturen en de upload niet meer afronden. |
| 409 | `idempotency_conflict` | Nee | Je hebt deze `Idempotency-Key` eerder met andere parameters gebruikt. |
| 413 | `media_too_large` | Nee | Het bestand overschrijdt je uploadlimiet. Bekijk [Bestanden uploaden](https://transcript1.com/nl/docs/uploads). |
| 413 | `invalid_request` | Nee | De JSON-body is groter dan 1 MB. Bij te grote bestanden krijg je `media_too_large`. |
| 429 | `rate_limited` | Ja | Je stuurt te veel requests per minuut. Wacht het aantal seconden uit `Retry-After`. |
| 429 | `too_many_active_jobs` | Ja | Er lopen te veel transcripties of er staan te veel uploads open. Wacht het aantal seconden uit `Retry-After`. |
| 500 | `internal_error` | Ja | Er gaat iets mis bij transcript1. Probeer het na een korte pauze opnieuw. |
| 503 | `service_unavailable` | Ja | transcript1 is even niet beschikbaar. Probeer het na een korte pauze opnieuw. |

Bij browserrequests met een inlogcookie controleren we ook vanaf welke site het request komt. Een andere site krijgt `403 forbidden_origin`. Voor API-requests met een bearer-token in de `Authorization`-header geldt die controle niet.

In elke `429`-response staat `Retry-After`: het aantal seconden dat je moet wachten. De limieten zelf vind je bij [Minuten, abonnementen en limieten](https://transcript1.com/nl/docs/billing-and-limits).

## Wanneer stuur je een request opnieuw?

- Herhaal alleen requests met `retryable` op `true`: `rate_limited`, `too_many_active_jobs`, `internal_error` en `service_unavailable`. Houd de wachttijd uit `Retry-After` aan. Ontbreekt die header, wacht dan bij elke poging langer.
- Herhaal je `POST /v1/transcriptions`, gebruik dan dezelfde `Idempotency-Key`-header. Zo betaal je niet dubbel als het eerste request toch is gelukt.
- Pas bij alle andere codes eerst je request aan voordat je het nog eens verstuurt.

## Als een transcriptie later mislukt

Ook na een geslaagd request kan de transcriptie nog mislukken. Dan krijg je `status` op `failed` en `error: { "code", "message" }` in het object. Controleer `error` dus ook tijdens het pollen of bij een [webhook](https://transcript1.com/nl/docs/webhooks) van het type `transcription.failed`.

| `error.code` | Wat is er mis? | Wat kun je doen? |
|---|---|---|
| `media_unavailable` | De video bestaat niet of is niet meer beschikbaar. | Niet opnieuw proberen. Controleer de URL. |
| `media_private` | De video is afgeschermd. | Gebruik een openbare post of een openbare of verborgen YouTube-video. Hetzelfde request herhalen helpt niet. |
| `login_required` | Je moet op het platform ingelogd zijn om de video te bekijken. | Niet opnieuw proberen. Deze fout is definitief; we proberen het niet automatisch opnieuw. |
| `no_audio` | Er zit geen audiospoor in de video. | Niet opnieuw proberen. Deze fout is definitief; we proberen het niet automatisch opnieuw. |
| `age_restricted` | De video heeft een leeftijdsbeperking. | Hetzelfde request herhalen helpt niet. Upload het bestand. |
| `live_stream` | De uitzending loopt nog of is nog niet begonnen. | Probeer het na afloop van de uitzending. |
| `no_captions` | Je zette `source` op `captions`, maar er is geen bruikbaar ondertitelspoor. | Kies `source: "auto"` of `"stt"`. |
| `media_too_long` | De opname duurt langer dan de 5 uur die speech-to-text aankan. | Splits het bestand. Hetzelfde request herhalen helpt niet. |
| `unsupported_media` | Het bestand is niet leesbaar of heeft geen audiospoor. | Stuur een ondersteund bestand; herhaal niet hetzelfde request. |
| `no_speech` | Geen spraak gedetecteerd. | Niet opnieuw proberen. |
| `unsupported_language` | We ondersteunen de taal van deze opname niet. | Kies voor `language` een ondersteunde code of `"auto"`; probeer niet opnieuw met dezelfde instelling. |
| `insufficient_minutes` | Je saldo was op voordat we de minuten konden afschrijven. | Koop eerst minuten bij en probeer het dan opnieuw. |
| `fetch_failed` | Ook na meerdere pogingen konden we de opname niet ophalen. | Probeer het later opnieuw. |
| `transcription_failed` | Ook na meerdere pogingen lukte speech-to-text niet. | Probeer het later opnieuw. |

Mislukt een transcriptie of annuleer je die, dan betaal je niets. Hadden we al minuten afgeschreven, dan krijg je die terug.
