Batch mode

View as Markdown

Batch mode provides asynchronous transcription for large or complex jobs that require processing multiple files or lengthy recordings.

Capabilities

  • Parallel file processing
  • Asynchronous operation
  • Large-scale recording support
  • Multi-speaker and multi-channel audio support
  • Language detection, model selection, custom vocabulary, and Text Polishing (en-US only, without language detection)

Each audio file generates its own transcript that saves to a corresponding output location.

How it works

Batch mode processing runs asynchronously and enables you to transcribe multiple files in a single API call.

This mode is ideal for workflows that involve large file collections.

Input

The API supports three input modes.

ModeDescription
SINGLEA single audio file. Inferred when the URI points to a single file.
PREFIXAll files under a shared S3 prefix/container. Supports glob filters to include or exclude files.
MANIFESTAn explicit list of file URIs. Maximum 1,000 files per manifest.

Output

The API supports three output layouts.

LayoutDescription
SINGLEUse the output URI as a single transcript file path. Valid only with SINGLE input. The uri can be a pre-signed HTTPS URL, in which case auth isn't needed.
ADJACENTPlace each transcript next to its input file (same directory). Valid only with PREFIX input. No output uri is needed, but destination is required.
PREFIXUse the output URI as the base directory for all transcripts. Required for MANIFEST input.

With PREFIX and ADJACENT layouts, each transcript is named after its input file with a unique suffix, such as a1.wav_8931d872-85bd-4fdf-b133-822c4090e008.json. With the SINGLE layout, the transcript is written to the exact output uri.

Audio requirements

  • Formats: WAV, MP3, M4A, MP4, and WebM
  • Channels: Mono or stereo
  • Sample rate: At least 8 kHz; 16 kHz or greater is recommended
  • Maximum duration per file: 2 hours
  • Maximum size per file: 300 MB

Transcription options

These options control recognition. For full descriptions, see Speech configuration.

ParameterTypeDefaultDescription
languagestringen-USLanguage code, such as en-US. See Speech configuration for supported languages.
segmentation_modestring"auto"Voice Activity Detection (VAD) mode. Set "none" to disable.
word_time_offsetsbooleanfalseInclude word-level timestamps.
channel_separationbooleanfalseTranscribe stereo channels separately.
diarizationbooleanfalseIdentify speakers and add a speaker tag to each transcript segment.
modelstringAutomaticSelect a compatible recognition model.
language_detectionobject—Detect each file's language once or continuously. Omit model when mode is once.
profanity_filterbooleanfalseFilter profanity when supported by the selected model.
text_polishingobject—Whether to return polished text. enabled boolean defaults to false. See Text Polishing.
vocabularyobject—Apply an inline phrase list to every file in the job.
vocabulary_idstring—Apply a persistent Vocabulary Asset.

For model and language options, see Speech configuration. For vocabulary options, see Custom vocabulary.

Batch jobs

Create a batch job

To create a new batch transcription job, use this endpoint:

POST /aiservices/scribe/jobs

You can optionally include a reference_id for tracking.

To receive webhook notifications when a job finishes, include a notifications object with a webhook_url and a secret for payload verification.

Example request (cURL)

This cURL example submits a batch transcription job from S3 and defines the output location and settings. The response returns a job ID and status so you can track processing.

curl -X POST https://api.zoom.us/v2/aiservices/scribe/jobs \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "input": {
      "mode": "PREFIX",
      "source": "S3",
      "uri": "s3://acme-bucket/audio/2026/10/",
      "filters": {
        "include_globs": ["**/*.wav", "**/*.mp3"],
        "exclude_globs": ["**/tmp/**"]
      },
      "auth": {
        "aws": {
          "access_key_id": "AKIA...",
          "secret_access_key": "wJalrX...",
          "session_token": "FwoGZXIvYXdzE..."
        }
      }
    },
    "output": {
      "destination": "S3",
      "uri": "s3://acme-bucket/transcripts/2026/10/",
      "layout": "PREFIX",
      "auth": {
        "aws": {
          "access_key_id": "AKIA...",
          "secret_access_key": "wJalrX...",
          "session_token": "FwoGZXIvYXdzE..."
        }
      }
    },
    "config": {
      "language": "en-US",
      "model": "zoom-scribe-en",
      "word_time_offsets": true,
      "channel_separation": false,
      "diarization": false
    },
    "outputs": {
      "text_polishing": {
        "enabled": true
      }
    },
    "notifications": {
      "webhook_url": "https://example.com/hooks/scribe",
      "secret": "hmac-secret"
    },
    "reference_id": "import-2025-11"
  }'

Use temporary AWS STS credentials in auth.aws, including session_token.

Each completed output file contains the original transcript. When Text Polishing is enabled, the file also contains outputs.text_polishing.text. See Text Polishing.

Response (201)

{
    "job_id": "8e5a1f3c-2d7b-4c9e-a6f1-0b4d7e2c9a58",
    "state": "QUEUED",
    "submitted_at": "2026-01-05T18:34:12Z"
}

Batch job endpoints

Five additional endpoints are available to manage batch jobs.

ActionDescriptionEndpoint
Get batch job statusCheck the current status and progress summary of a specific job.GET /aiservices/scribe/jobs/{jobId}
List batch jobsView all batch jobs, optionally filtered by state.GET /aiservices/scribe/jobs?state=QUEUED&page_size=50&next_page_token=...
Cancel batch jobCancel a job that is in QUEUED or PROCESSING state.DELETE /aiservices/scribe/jobs/{jobId}
List batch job filesRetrieve per-file status with pagination.GET /aiservices/scribe/jobs/{jobId}/files?page_size=200&next_page_token=...
Get batch job fileRetrieve the status and output location of an individual file.GET /aiservices/scribe/jobs/{jobId}/files/{fileId}

List responses include a next_cursor field. Pass its value as the next_page_token query parameter to retrieve the next page.

Job and file states

Files in a job are processed independently. If any file fails or is skipped while others succeed, the job ends in PARTIAL. The job status response includes a summary with counts for total_files, queued, processing, succeeded, failed, skipped, and canceled.

Job stateDescription
QUEUEDThe job is waiting to start.
PROCESSINGFiles are being transcribed.
SUCCEEDEDAll files were transcribed.
PARTIALSome files were transcribed, and some failed or were skipped.
FAILEDThe job failed.
CANCELEDThe job was canceled. This is a terminal state.
File stateDescription
FILE_QUEUEDThe file is waiting to be processed.
FILE_PROCESSINGThe file is being transcribed.
FILE_SUCCEEDEDThe transcript was written to the output location.
FILE_FAILEDThe file couldn't be transcribed.
FILE_CANCELEDProcessing was canceled for the file.
FILE_SKIPPEDThe file was skipped because its extension isn't supported. The file's error.code is UNSUPPORTED_MEDIA.

Webhook verification

When you provide a secret in the notifications object, the API signs each webhook request so you can verify that Zoom AI Services sent it.

Each webhook request includes two headers.

HeaderDescription
x-zm-signatureHMAC-SHA256 signature of the request, prefixed with sha256=
x-zm-request-timestampUnix timestamp of when the request was sent

To verify the signature:

  1. Compute the HMAC-SHA256 of the string v0:{timestamp}:{raw_body} using your secret key
  2. Compare it with the value in x-zm-signature using a timing-safe comparison to prevent timing attacks.
  3. Reject the request if the signatures do not match or if the timestamp is stale.
const message = `v0:${timestamp}:${rawBody}`;
const expected = `sha256=${crypto.createHmac('sha256', secret).update(message).digest('hex')}`;
const a = Buffer.from(signature);
const b = Buffer.from(expected);
const isValid = a.length === b.length && crypto.timingSafeEqual(a, b);