Status Codes & Errors
⚠️ Status Codes & Errors
Section titled “⚠️ Status Codes & Errors”The Uspeech API follows conventional REST semantics. The HTTP status code is the source of truth for whether a request succeeded; the response body adds detail.
HTTP status codes
Section titled “HTTP status codes”| Code | Meaning |
|---|---|
200 OK | Successful read (GET) or action returning a body. |
201 Created | A new resource was created (typically a file upload). |
202 Accepted | The request was accepted and work has been queued asynchronously. |
204 No Content | Successful action with no body to return. |
400 Bad Request | The request body or query parameters are invalid. The response body describes which fields. |
401 Unauthorized | No credentials were supplied. Add the Authorization: Api-Key … header. |
403 Forbidden | Credentials are missing, malformed, revoked, the user is inactive, or the user has no access to the resource. |
404 Not Found | The resource doesn’t exist — or exists but isn’t visible to the caller. |
429 Too Many Requests | Rate limit exceeded. Retry after a short delay. |
5xx | An unexpected server error. Safe to retry idempotent reads; check status before retrying writes. |
Error response shape
Section titled “Error response shape”DRF returns errors as JSON. The exact shape depends on what failed:
Validation error (per-field):
{ "project": ["This field is required."], "file": ["No file was submitted."]}Generic error (auth, not-found, etc.):
{ "detail": "Authentication credentials were not provided."}Subscription / usage error:
{ "detail": "Free trial limit exceeded.", "reason": "free_trial_exceeded"}Always check the HTTP status first; use the body for human-readable detail.
Transcription-specific failure reasons
Section titled “Transcription-specific failure reasons”A transcription job can complete the request lifecycle (HTTP 201 on upload) and still fail asynchronously in the background. When that happens, status becomes failed and the error_reason field — returned by both GET /api/files/{id}/ and GET /api/transcripts/{id}/ — tells you why:
error_reason | When it’s set |
|---|---|
audio_too_short | The audio is below the minimum length needed for transcription — typically empty or beep-only recordings. |
hallucinated_transcript | A safeguard fired: the model returned text whose timestamps extend far past the actual audio duration, which usually signals a fabricated transcript. |
If error_reason is empty on a failed transcript, the cause is upstream (storage, model API, etc.) — check server logs or contact support.
💡 Tip: when polling GET /api/files/{id}/, treat failed as terminal. Don’t retry blindly — for audio_too_short the file genuinely has nothing to transcribe; for hallucinated_transcript, re-uploading the same audio will likely produce the same result.
Authentication failures
Section titled “Authentication failures”A few common pitfalls return 401 or 403:
- Header is exactly
Authorization: Api-Key <key>(with the space afterApi-Key). - The plaintext key is
<prefix>.<secret>— both halves must be sent. - A revoked key returns
403even if it was previously valid. - An inactive user (
is_active = False) cannot use the key.
See Authentication for the full setup.