---
title: Submit a transcription job
description: Submit one complete recording for asynchronous Batch transcription.
icon: ArrowUpFromLine
full: true
_openapi:
  method: POST
  webhook: false
  toc: []
  structuredData:
    headings: []
    contents:
      - content: |
          Submit one complete recording for asynchronous Batch transcription. Use
          Batch for long or large complete media; use Fast for one complete,
          bounded, latency-sensitive conversational unit, and Realtime only while
          audio is still arriving.

          A `200` response means the job was accepted with status `queued`, not
          that transcription finished. Persist `jobId`, then poll
          `GET /transcribe/{job_id}` until `done`, `failed`, or `cleared`.

          This operation has no idempotency-key contract. Do not blindly replay an
          upload after a timeout, connection loss, or `5xx`: the job may already
          exist and a replay can create duplicate work. A `429` response is
          capacity backpressure; `data.capacity` is remaining audio capacity in
          seconds when a balance is available, not a delay or reset time.
---


## Operation

**POST `/transcribe/{lang}`**

- **Base URL:** `https://api.voice.humain.com/v1`
- **Request URL:** `https://api.voice.humain.com/v1/transcribe/{lang}`

## Description

Submit one complete recording for asynchronous Batch transcription. Use
Batch for long or large complete media; use Fast for one complete,
bounded, latency-sensitive conversational unit, and Realtime only while
audio is still arriving.

A `200` response means the job was accepted with status `queued`, not
that transcription finished. Persist `jobId`, then poll
`GET /transcribe/{job_id}` until `done`, `failed`, or `cleared`.

This operation has no idempotency-key contract. Do not blindly replay an
upload after a timeout, connection loss, or `5xx`: the job may already
exist and a replay can create duplicate work. A `429` response is
capacity backpressure; `data.capacity` is remaining audio capacity in
seconds when a balance is available, not a delay or reset time.

## Authentication

- `ApiKeyAuth` — type: `apiKey`; Location: `header`; Headers: `x-api-key`

## Parameters

### Parameter `lang`

- **Location:** `path`
- **Required:** yes
- **Type:** `string`

Language code for transcription.

**Schema:**

```yaml
type: string
enum:
  - en
  - ar
  - codeswitch
  - auto
```

**Examples:**

None documented.

### Parameter `asr`

- **Location:** `query`
- **Required:** no
- **Type:** `string`

Optional exact ASR model key. When omitted, the service uses the
configured default for the selected `lang`. An unknown key or a
missing configured default returns `400` with `ASR_MODEL_NOT_FOUND`.

**Schema:**

```yaml
type: string
```

**Examples:**

None documented.

### Parameter `diarization`

- **Location:** `query`
- **Required:** no
- **Type:** `string`

Speaker diarization selector:
- omitted, `0`, or `false`: Disabled
- `1` or `true`: Enabled with default model
- `d1`: Speaker diarization
- `d2`: Speaker diarization (alternative)

**Schema:**

```yaml
type: string
enum:
  - "0"
  - "1"
  - "false"
  - "true"
  - d1
  - d2
```

**Examples:**

```yaml
enable:
  value: "1"
disable:
  value: "0"
enable_boolean:
  value: "true"
disable_boolean:
  value: "false"
d1:
  value: d1
d2:
  value: d2
```

### Parameter `itn`

- **Location:** `query`
- **Required:** no
- **Type:** `string`

Inverse Text Normalization (ITN) selector:
- omitted, `0`, or `false`: Disabled
- `1` or `true`: Enabled (converts spoken forms to written, e.g., "twenty five" → "25")

**Schema:**

```yaml
type: string
enum:
  - "0"
  - "1"
  - "false"
  - "true"
```

**Examples:**

```yaml
enable:
  value: "1"
disable:
  value: "0"
enable_boolean:
  value: "true"
disable_boolean:
  value: "false"
```

### Parameter `redact`

- **Location:** `query`
- **Required:** no
- **Type:** `string`

PII Redaction selector:
- omitted, `0`, or `false`: Disabled
- `1` or `true`: Enabled (masks sensitive information in transcripts)

**Schema:**

```yaml
type: string
enum:
  - "0"
  - "1"
  - "false"
  - "true"
```

**Examples:**

```yaml
enable:
  value: "1"
disable:
  value: "0"
enable_boolean:
  value: "true"
disable_boolean:
  value: "false"
```

## Request body

- **Required:** yes

#### Content type: `multipart/form-data`

**Schema:**

```yaml
type: object
required:
  - file
properties:
  file:
    type: string
    description: |
      One complete audio recording, and the only audio part accepted.
      Unsupported, corrupt, empty, or zero-duration input returns `422`.
      A recording longer than the decoded-duration limit returns `422`
      `AUDIO_DURATION_EXCEEDED`; a second audio part returns `422`
      `FILE_COUNT_EXCEEDED`. See "Request limits".
    contentMediaType: application/octet-stream
```

**Examples:**

None documented.

## Responses

### Response `200`

Job accepted and queued for asynchronous processing

#### Content type: `application/json`

**Schema:**

```yaml
type: object
required:
  - jobId
  - status
properties:
  jobId:
    type: string
    format: uuid
  status:
    type: string
    enum:
      - queued
    examples:
      - queued
```

**Examples:**

```yaml
queued:
  value:
    jobId: 7f51f2c2-e7bc-41c8-a850-f848df2ddfc8
    status: queued
```

### Response `400`

Invalid language, model, content type, multipart body, or file field

#### Content type: `application/json`

**Schema:**

```yaml
type: object
required:
  - error
  - code
  - retryable
  - timestamp
properties:
  error:
    type: string
    description: Legacy error identifier (frozen for backward compatibility)
  message:
    type: string
    description: Legacy message field (present only on auth missing-key errors)
  code:
    type: string
    description: |
      Machine-readable error code. This enumeration is the set this
      service emits in an `ErrorResponse` body. The `429` rate-limit
      response uses `RateLimitErrorResponse` and carries
      `RATE_LIMIT_EXCEEDED` instead.
    enum:
      - AUTH_UNAUTHORIZED
      - AUTH_FORBIDDEN
      - VALIDATION_INVALID_LANGUAGE
      - VALIDATION_INVALID_FORMAT
      - VALIDATION_REQUIRED_FIELD
      - VALIDATION_FILE_CORRUPT
      - VALIDATION_INVALID_PARAM
      - VALIDATION_INVALID_UUID
      - PAYLOAD_TOO_LARGE
      - AUDIO_DURATION_EXCEEDED
      - FILE_COUNT_EXCEEDED
      - ASR_TRANSCRIPTION_FAILED
      - ASR_MODEL_NOT_FOUND
      - SERVER_INTERNAL
      - TRANSCRIPTION_JOB_NOT_FOUND
  detail:
    type: string
    description: Human-readable error explanation
  job_id:
    type: string
    description: |
      Job identifier supplied by the client. It can be a valid UUID for
      post-creation errors or the invalid submitted value when `code` is
      `VALIDATION_INVALID_UUID`.
  retryable:
    type: boolean
    description: Whether the client should retry this request
  timestamp:
    type: string
    format: date-time
    description: ISO 8601 timestamp of when the error occurred
  request_id:
    type: string
    description: |
      Trace identifier for this request, for correlation in a support request.
      Present on request-limit rejections; absent when tracing is not recording.
  data:
    allOf:
      - type: object
        required:
          - limit
          - observed
          - unit
          - bound
        description: The limit that was exceeded, its configured value and what was observed.
        properties:
          limit:
            type: integer
            format: int64
            description: The configured maximum, in `unit`.
          observed:
            type: integer
            format: int64
            description: |
              The observed value, in `unit`. Always greater than `limit`. Durations are
              rounded up, so a recording a fraction of a second over the ceiling still
              reports a value above it.
          unit:
            type: string
            enum:
              - bytes
              - seconds
              - files
              - parts
          bound:
            type: string
            description: Which limit was exceeded.
            enum:
              - request_bytes
              - audio_duration
              - file_parts
              - multipart_parts
              - unvalidatable_tail_bytes
    description: |
      Present only on a request-limit rejection (`PAYLOAD_TOO_LARGE`,
      `AUDIO_DURATION_EXCEEDED`, `FILE_COUNT_EXCEEDED`). Absent otherwise.
```

**Examples:**

```yaml
invalid_language:
  summary: Invalid language
  value:
    error: error.language.invalid
    code: VALIDATION_INVALID_LANGUAGE
    detail: error.language.invalid
    retryable: false
    timestamp: 2026-01-15T10:30:00Z
invalid_content_type:
  summary: Request is not multipart form data
  value:
    error: error.api.error.request.invalid_format
    code: VALIDATION_INVALID_FORMAT
    detail: error.api.error.request.invalid_format
    retryable: false
    timestamp: 2026-01-15T10:30:00Z
missing_file:
  summary: First multipart field is not file
  value:
    error: error.api.error.multipart.file.missing
    code: VALIDATION_REQUIRED_FIELD
    detail: error.api.error.multipart.file.missing
    retryable: false
    timestamp: 2026-01-15T10:30:00Z
unknown_asr_model:
  summary: ASR model is not configured
  value:
    error: error.asr_model.not_found
    code: ASR_MODEL_NOT_FOUND
    detail: error.asr_model.not_found
    retryable: false
    timestamp: 2026-01-15T10:30:00Z
```

### Response `401`

Unauthorized

#### Content type: `application/json`

**Schema:**

```yaml
type: object
required:
  - error
  - code
  - retryable
  - timestamp
properties:
  error:
    type: string
    description: Legacy error identifier (frozen for backward compatibility)
  message:
    type: string
    description: Legacy message field (present only on auth missing-key errors)
  code:
    type: string
    description: |
      Machine-readable error code. This enumeration is the set this
      service emits in an `ErrorResponse` body. The `429` rate-limit
      response uses `RateLimitErrorResponse` and carries
      `RATE_LIMIT_EXCEEDED` instead.
    enum:
      - AUTH_UNAUTHORIZED
      - AUTH_FORBIDDEN
      - VALIDATION_INVALID_LANGUAGE
      - VALIDATION_INVALID_FORMAT
      - VALIDATION_REQUIRED_FIELD
      - VALIDATION_FILE_CORRUPT
      - VALIDATION_INVALID_PARAM
      - VALIDATION_INVALID_UUID
      - PAYLOAD_TOO_LARGE
      - AUDIO_DURATION_EXCEEDED
      - FILE_COUNT_EXCEEDED
      - ASR_TRANSCRIPTION_FAILED
      - ASR_MODEL_NOT_FOUND
      - SERVER_INTERNAL
      - TRANSCRIPTION_JOB_NOT_FOUND
  detail:
    type: string
    description: Human-readable error explanation
  job_id:
    type: string
    description: |
      Job identifier supplied by the client. It can be a valid UUID for
      post-creation errors or the invalid submitted value when `code` is
      `VALIDATION_INVALID_UUID`.
  retryable:
    type: boolean
    description: Whether the client should retry this request
  timestamp:
    type: string
    format: date-time
    description: ISO 8601 timestamp of when the error occurred
  request_id:
    type: string
    description: |
      Trace identifier for this request, for correlation in a support request.
      Present on request-limit rejections; absent when tracing is not recording.
  data:
    allOf:
      - type: object
        required:
          - limit
          - observed
          - unit
          - bound
        description: The limit that was exceeded, its configured value and what was observed.
        properties:
          limit:
            type: integer
            format: int64
            description: The configured maximum, in `unit`.
          observed:
            type: integer
            format: int64
            description: |
              The observed value, in `unit`. Always greater than `limit`. Durations are
              rounded up, so a recording a fraction of a second over the ceiling still
              reports a value above it.
          unit:
            type: string
            enum:
              - bytes
              - seconds
              - files
              - parts
          bound:
            type: string
            description: Which limit was exceeded.
            enum:
              - request_bytes
              - audio_duration
              - file_parts
              - multipart_parts
              - unvalidatable_tail_bytes
    description: |
      Present only on a request-limit rejection (`PAYLOAD_TOO_LARGE`,
      `AUDIO_DURATION_EXCEEDED`, `FILE_COUNT_EXCEEDED`). Absent otherwise.
```

**Examples:**

```yaml
missing_key:
  value:
    error: auth.unauthorized
    message: unauthorized
    code: AUTH_UNAUTHORIZED
    retryable: false
    timestamp: 2026-01-15T10:30:00Z
```

### Response `403`

The API key does not grant batch transcription access

#### Content type: `application/json`

**Schema:**

```yaml
type: object
required:
  - error
  - code
  - retryable
  - timestamp
properties:
  error:
    type: string
    description: Legacy error identifier (frozen for backward compatibility)
  message:
    type: string
    description: Legacy message field (present only on auth missing-key errors)
  code:
    type: string
    description: |
      Machine-readable error code. This enumeration is the set this
      service emits in an `ErrorResponse` body. The `429` rate-limit
      response uses `RateLimitErrorResponse` and carries
      `RATE_LIMIT_EXCEEDED` instead.
    enum:
      - AUTH_UNAUTHORIZED
      - AUTH_FORBIDDEN
      - VALIDATION_INVALID_LANGUAGE
      - VALIDATION_INVALID_FORMAT
      - VALIDATION_REQUIRED_FIELD
      - VALIDATION_FILE_CORRUPT
      - VALIDATION_INVALID_PARAM
      - VALIDATION_INVALID_UUID
      - PAYLOAD_TOO_LARGE
      - AUDIO_DURATION_EXCEEDED
      - FILE_COUNT_EXCEEDED
      - ASR_TRANSCRIPTION_FAILED
      - ASR_MODEL_NOT_FOUND
      - SERVER_INTERNAL
      - TRANSCRIPTION_JOB_NOT_FOUND
  detail:
    type: string
    description: Human-readable error explanation
  job_id:
    type: string
    description: |
      Job identifier supplied by the client. It can be a valid UUID for
      post-creation errors or the invalid submitted value when `code` is
      `VALIDATION_INVALID_UUID`.
  retryable:
    type: boolean
    description: Whether the client should retry this request
  timestamp:
    type: string
    format: date-time
    description: ISO 8601 timestamp of when the error occurred
  request_id:
    type: string
    description: |
      Trace identifier for this request, for correlation in a support request.
      Present on request-limit rejections; absent when tracing is not recording.
  data:
    allOf:
      - type: object
        required:
          - limit
          - observed
          - unit
          - bound
        description: The limit that was exceeded, its configured value and what was observed.
        properties:
          limit:
            type: integer
            format: int64
            description: The configured maximum, in `unit`.
          observed:
            type: integer
            format: int64
            description: |
              The observed value, in `unit`. Always greater than `limit`. Durations are
              rounded up, so a recording a fraction of a second over the ceiling still
              reports a value above it.
          unit:
            type: string
            enum:
              - bytes
              - seconds
              - files
              - parts
          bound:
            type: string
            description: Which limit was exceeded.
            enum:
              - request_bytes
              - audio_duration
              - file_parts
              - multipart_parts
              - unvalidatable_tail_bytes
    description: |
      Present only on a request-limit rejection (`PAYLOAD_TOO_LARGE`,
      `AUDIO_DURATION_EXCEEDED`, `FILE_COUNT_EXCEEDED`). Absent otherwise.
```

**Examples:**

```yaml
scope_denied:
  value:
    error: error.api_key.scope_denied
    code: AUTH_FORBIDDEN
    detail: scope not permitted
    retryable: false
    timestamp: 2026-01-15T10:30:00Z
```

### Response `413`

The request exceeded the byte limit. No job was created and no transcription was
started. `data.observed` is the client's declared
`Content-Length` when it already exceeded the limit; when the body was rejected
while being read it is `limit + 1`, the smallest provable size, because reading
stops there.

#### Content type: `application/json`

**Schema:**

```yaml
type: object
required:
  - error
  - code
  - retryable
  - timestamp
properties:
  error:
    type: string
    description: Legacy error identifier (frozen for backward compatibility)
  message:
    type: string
    description: Legacy message field (present only on auth missing-key errors)
  code:
    type: string
    description: |
      Machine-readable error code. This enumeration is the set this
      service emits in an `ErrorResponse` body. The `429` rate-limit
      response uses `RateLimitErrorResponse` and carries
      `RATE_LIMIT_EXCEEDED` instead.
    enum:
      - AUTH_UNAUTHORIZED
      - AUTH_FORBIDDEN
      - VALIDATION_INVALID_LANGUAGE
      - VALIDATION_INVALID_FORMAT
      - VALIDATION_REQUIRED_FIELD
      - VALIDATION_FILE_CORRUPT
      - VALIDATION_INVALID_PARAM
      - VALIDATION_INVALID_UUID
      - PAYLOAD_TOO_LARGE
      - AUDIO_DURATION_EXCEEDED
      - FILE_COUNT_EXCEEDED
      - ASR_TRANSCRIPTION_FAILED
      - ASR_MODEL_NOT_FOUND
      - SERVER_INTERNAL
      - TRANSCRIPTION_JOB_NOT_FOUND
  detail:
    type: string
    description: Human-readable error explanation
  job_id:
    type: string
    description: |
      Job identifier supplied by the client. It can be a valid UUID for
      post-creation errors or the invalid submitted value when `code` is
      `VALIDATION_INVALID_UUID`.
  retryable:
    type: boolean
    description: Whether the client should retry this request
  timestamp:
    type: string
    format: date-time
    description: ISO 8601 timestamp of when the error occurred
  request_id:
    type: string
    description: |
      Trace identifier for this request, for correlation in a support request.
      Present on request-limit rejections; absent when tracing is not recording.
  data:
    allOf:
      - type: object
        required:
          - limit
          - observed
          - unit
          - bound
        description: The limit that was exceeded, its configured value and what was observed.
        properties:
          limit:
            type: integer
            format: int64
            description: The configured maximum, in `unit`.
          observed:
            type: integer
            format: int64
            description: |
              The observed value, in `unit`. Always greater than `limit`. Durations are
              rounded up, so a recording a fraction of a second over the ceiling still
              reports a value above it.
          unit:
            type: string
            enum:
              - bytes
              - seconds
              - files
              - parts
          bound:
            type: string
            description: Which limit was exceeded.
            enum:
              - request_bytes
              - audio_duration
              - file_parts
              - multipart_parts
              - unvalidatable_tail_bytes
    description: |
      Present only on a request-limit rejection (`PAYLOAD_TOO_LARGE`,
      `AUDIO_DURATION_EXCEEDED`, `FILE_COUNT_EXCEEDED`). Absent otherwise.
```

**Examples:**

```yaml
declared_too_large:
  summary: Content-Length already exceeds the limit
  value:
    error: error.api.error.request.too_large
    code: PAYLOAD_TOO_LARGE
    detail: error.api.error.request.too_large
    retryable: false
    timestamp: 2026-01-15T10:30:00Z
    request_id: 4bf92f3577b34da6a3ce929d0e0e4736
    data:
      limit: 536870912
      observed: 1073741824
      unit: bytes
      bound: request_bytes
unvalidatable_tail:
  summary: Too much data beyond the recording to finish checking the limits
  value:
    error: error.api.error.request.unvalidatable_tail
    code: PAYLOAD_TOO_LARGE
    detail: error.api.error.request.unvalidatable_tail
    retryable: false
    timestamp: 2026-01-15T10:30:00Z
    data:
      limit: 524288
      observed: 524289
      unit: bytes
      bound: unvalidatable_tail_bytes
overran_while_reading:
  summary: Body overran the limit mid-stream
  value:
    error: error.api.error.request.too_large
    code: PAYLOAD_TOO_LARGE
    detail: error.api.error.request.too_large
    retryable: false
    timestamp: 2026-01-15T10:30:00Z
    data:
      limit: 536870912
      observed: 536870913
      unit: bytes
      bound: request_bytes
```

### Response `422`

Unsupported or corrupt audio input, or a valid request whose workload exceeds a
semantic limit. No job was created and no transcription was started; see
"Request limits" for when audio is converted before the rejection.

#### Content type: `application/json`

**Schema:**

```yaml
type: object
required:
  - error
  - code
  - retryable
  - timestamp
properties:
  error:
    type: string
    description: Legacy error identifier (frozen for backward compatibility)
  message:
    type: string
    description: Legacy message field (present only on auth missing-key errors)
  code:
    type: string
    description: |
      Machine-readable error code. This enumeration is the set this
      service emits in an `ErrorResponse` body. The `429` rate-limit
      response uses `RateLimitErrorResponse` and carries
      `RATE_LIMIT_EXCEEDED` instead.
    enum:
      - AUTH_UNAUTHORIZED
      - AUTH_FORBIDDEN
      - VALIDATION_INVALID_LANGUAGE
      - VALIDATION_INVALID_FORMAT
      - VALIDATION_REQUIRED_FIELD
      - VALIDATION_FILE_CORRUPT
      - VALIDATION_INVALID_PARAM
      - VALIDATION_INVALID_UUID
      - PAYLOAD_TOO_LARGE
      - AUDIO_DURATION_EXCEEDED
      - FILE_COUNT_EXCEEDED
      - ASR_TRANSCRIPTION_FAILED
      - ASR_MODEL_NOT_FOUND
      - SERVER_INTERNAL
      - TRANSCRIPTION_JOB_NOT_FOUND
  detail:
    type: string
    description: Human-readable error explanation
  job_id:
    type: string
    description: |
      Job identifier supplied by the client. It can be a valid UUID for
      post-creation errors or the invalid submitted value when `code` is
      `VALIDATION_INVALID_UUID`.
  retryable:
    type: boolean
    description: Whether the client should retry this request
  timestamp:
    type: string
    format: date-time
    description: ISO 8601 timestamp of when the error occurred
  request_id:
    type: string
    description: |
      Trace identifier for this request, for correlation in a support request.
      Present on request-limit rejections; absent when tracing is not recording.
  data:
    allOf:
      - type: object
        required:
          - limit
          - observed
          - unit
          - bound
        description: The limit that was exceeded, its configured value and what was observed.
        properties:
          limit:
            type: integer
            format: int64
            description: The configured maximum, in `unit`.
          observed:
            type: integer
            format: int64
            description: |
              The observed value, in `unit`. Always greater than `limit`. Durations are
              rounded up, so a recording a fraction of a second over the ceiling still
              reports a value above it.
          unit:
            type: string
            enum:
              - bytes
              - seconds
              - files
              - parts
          bound:
            type: string
            description: Which limit was exceeded.
            enum:
              - request_bytes
              - audio_duration
              - file_parts
              - multipart_parts
              - unvalidatable_tail_bytes
    description: |
      Present only on a request-limit rejection (`PAYLOAD_TOO_LARGE`,
      `AUDIO_DURATION_EXCEEDED`, `FILE_COUNT_EXCEEDED`). Absent otherwise.
```

**Examples:**

```yaml
unsupported_audio:
  value:
    error: unsupported or corrupt audio input for conversion
    code: VALIDATION_FILE_CORRUPT
    detail: unsupported or corrupt audio input for conversion
    retryable: false
    timestamp: 2026-01-15T10:30:00Z
audio_too_long:
  summary: Decoded audio exceeds the duration limit
  value:
    error: error.api.error.audio.duration_exceeded
    code: AUDIO_DURATION_EXCEEDED
    detail: error.api.error.audio.duration_exceeded
    retryable: false
    timestamp: 2026-01-15T10:30:00Z
    request_id: 4bf92f3577b34da6a3ce929d0e0e4736
    data:
      limit: 14400
      observed: 21600
      unit: seconds
      bound: audio_duration
too_many_files:
  summary: More than one audio part was submitted
  value:
    error: error.api.error.multipart.file.count_exceeded
    code: FILE_COUNT_EXCEEDED
    detail: error.api.error.multipart.file.count_exceeded
    retryable: false
    timestamp: 2026-01-15T10:30:00Z
    data:
      limit: 1
      observed: 2
      unit: files
      bound: file_parts
too_many_parts:
  summary: More multipart parts than the request allows
  value:
    error: error.api.error.multipart.part.count_exceeded
    code: FILE_COUNT_EXCEEDED
    detail: error.api.error.multipart.part.count_exceeded
    retryable: false
    timestamp: 2026-01-15T10:30:00Z
    data:
      limit: 8
      observed: 9
      unit: parts
      bound: multipart_parts
```

### Response `429`

Audio capacity is exhausted. `data.capacity` is remaining audio seconds
when a balance is available; it is not a retry delay, reset timestamp,
or quota guarantee. A zero value can mean no balance was available.

#### Content type: `application/json`

**Schema:**

```yaml
type: object
required:
  - error
  - code
  - retryable
  - timestamp
  - data
properties:
  error:
    type: string
  code:
    type: string
    enum:
      - RATE_LIMIT_EXCEEDED
  detail:
    type: string
  retryable:
    type: boolean
  timestamp:
    type: string
    format: date-time
  data:
    type: object
    required:
      - capacity
    properties:
      capacity:
        type: number
        format: float
        description: |
          Remaining audio-processing capacity in seconds when a balance
          is available. This is not a retry delay or reset timestamp; zero
          can mean no balance was available.
```

**Examples:**

```yaml
limited:
  value:
    error: error.rate_limit
    code: RATE_LIMIT_EXCEEDED
    detail: error.rate_limit
    retryable: true
    timestamp: 2026-01-15T10:30:00Z
    data:
      capacity: 120.5
```

### Response `500`

Submission failed; the outcome can be ambiguous after job creation

#### Content type: `application/json`

**Schema:**

```yaml
type: object
required:
  - error
  - code
  - retryable
  - timestamp
properties:
  error:
    type: string
    description: Legacy error identifier (frozen for backward compatibility)
  message:
    type: string
    description: Legacy message field (present only on auth missing-key errors)
  code:
    type: string
    description: |
      Machine-readable error code. This enumeration is the set this
      service emits in an `ErrorResponse` body. The `429` rate-limit
      response uses `RateLimitErrorResponse` and carries
      `RATE_LIMIT_EXCEEDED` instead.
    enum:
      - AUTH_UNAUTHORIZED
      - AUTH_FORBIDDEN
      - VALIDATION_INVALID_LANGUAGE
      - VALIDATION_INVALID_FORMAT
      - VALIDATION_REQUIRED_FIELD
      - VALIDATION_FILE_CORRUPT
      - VALIDATION_INVALID_PARAM
      - VALIDATION_INVALID_UUID
      - PAYLOAD_TOO_LARGE
      - AUDIO_DURATION_EXCEEDED
      - FILE_COUNT_EXCEEDED
      - ASR_TRANSCRIPTION_FAILED
      - ASR_MODEL_NOT_FOUND
      - SERVER_INTERNAL
      - TRANSCRIPTION_JOB_NOT_FOUND
  detail:
    type: string
    description: Human-readable error explanation
  job_id:
    type: string
    description: |
      Job identifier supplied by the client. It can be a valid UUID for
      post-creation errors or the invalid submitted value when `code` is
      `VALIDATION_INVALID_UUID`.
  retryable:
    type: boolean
    description: Whether the client should retry this request
  timestamp:
    type: string
    format: date-time
    description: ISO 8601 timestamp of when the error occurred
  request_id:
    type: string
    description: |
      Trace identifier for this request, for correlation in a support request.
      Present on request-limit rejections; absent when tracing is not recording.
  data:
    allOf:
      - type: object
        required:
          - limit
          - observed
          - unit
          - bound
        description: The limit that was exceeded, its configured value and what was observed.
        properties:
          limit:
            type: integer
            format: int64
            description: The configured maximum, in `unit`.
          observed:
            type: integer
            format: int64
            description: |
              The observed value, in `unit`. Always greater than `limit`. Durations are
              rounded up, so a recording a fraction of a second over the ceiling still
              reports a value above it.
          unit:
            type: string
            enum:
              - bytes
              - seconds
              - files
              - parts
          bound:
            type: string
            description: Which limit was exceeded.
            enum:
              - request_bytes
              - audio_duration
              - file_parts
              - multipart_parts
              - unvalidatable_tail_bytes
    description: |
      Present only on a request-limit rejection (`PAYLOAD_TOO_LARGE`,
      `AUDIO_DURATION_EXCEEDED`, `FILE_COUNT_EXCEEDED`). Absent otherwise.
```

**Examples:**

```yaml
transcription_failed:
  value:
    error: error.api.transcription
    code: ASR_TRANSCRIPTION_FAILED
    detail: error.api.transcription
    retryable: true
    timestamp: 2026-01-15T10:30:00Z
```

## Next steps

Once the request returns a `jobId`, persist it before leaving your request handler. Then poll the V2 lookup with a bounded deadline until the job reaches `done`, `failed`, or `cleared`.

### [Poll the job with V2](/en/api-reference/batch/get-transcription-job)

Read the recommended direct HTTP status and result shape.

### [Build the Batch lifecycle](/en/api-guides/batch-rest)

Connect submission, bounded polling, and terminal-state handling.

### [Plan safe failure handling](/en/api-guides/errors-and-rate-limits)

Handle capacity pressure and ambiguous upload outcomes without blind retries.
