> ## Documentation Index
> Fetch the complete documentation index at: https://assemblyai.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Transcribe live audio



## OpenAPI

````yaml specs/sync-api.yaml POST /v1/transcribe/live
openapi: 3.1.0
info:
  title: AssemblyAI Sync STT API
  description: Synchronous short-form audio transcription using Universal-3.5 Pro.
  version: 1.0.0
servers:
  - url: https://sync.assemblyai.com
    description: Global (default — routes to nearest region)
  - url: https://sync.us.assemblyai.com
    description: US data residency (us-west-2, us-east-1)
  - url: https://sync.eu.assemblyai.com
    description: EU data residency (eu-north-1)
security:
  - ApiKey: []
paths:
  /v1/transcribe/live:
    post:
      summary: Transcribe live audio
      description: >
        Upload audio while it is still being recorded and receive one finished

        transcript when the audio ends. The request starts before the audio

        exists and the body is uploaded with `Transfer-Encoding: chunked`, so

        the upload and every speech segment but the last are transcribed while

        the caller is still recording. Audio must be between 80 ms and 120 s.


        The body is `multipart/form-data` with two differences from

        [`/transcribe`](/api-reference/sync-api/transcribe): the `config` part

        must be sent **before** the `audio` part (the server decodes audio as it

        arrives and needs `sample_rate`/`channels` first, so it rejects a body

        whose audio no config part came before — send `{}` when you have no

        options), and the body is streamed rather than buffered. The default

        request budget is 180 seconds, covering the recording as well as the

        transcription. This endpoint is also served at `/v1/transcribe/stream`,

        the path it shipped under.


        This endpoint is for short audio only: the maximum audio length is 120

        seconds, and it returns one finished transcript when the audio ends. For

        longer audio, or for words returned while the speaker is still talking,

        use the [Real-time STT
        API](/streaming/getting-started/transcribe-streaming-audio),

        which opens a WebSocket connection for up to 3 hours. See

        [Transcribe live audio](/sync-stt/getting-started/transcribe-live-audio)

        for the SDK sessions and full guidance.


        <Note>To use a data residency endpoint, replace `sync.assemblyai.com`
        with

        `sync.us.assemblyai.com` (US) or `sync.eu.assemblyai.com` (EU). See

        [Cloud Endpoints and Data Residency](/sync-stt/endpoints-and-data-zones)
        for more information.</Note>
      operationId: transcribeLiveSync
      parameters:
        - in: header
          name: X-AAI-Model
          required: true
          schema:
            type: string
            enum:
              - universal-3-5-pro
          description: >-
            Model identifier used for request routing. The canonical value is
            `universal-3-5-pro`; `u3-sync-pro` and `u3-pro` are accepted as
            legacy aliases.
        - in: query
          name: token
          required: false
          schema:
            type: string
          description: >-
            API key alternative for clients that cannot set the `Authorization`
            header. The header wins when both are present.
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required:
                - config
                - audio
              properties:
                config:
                  type: object
                  description: >-
                    Transcription configuration. Must be the first part, ahead
                    of `audio`. Send an empty object (`{}`) when you have no
                    options to set.
                  properties:
                    sample_rate:
                      type: integer
                      enum:
                        - 8000
                        - 16000
                        - 22050
                        - 24000
                        - 32000
                        - 44100
                        - 48000
                      description: >-
                        Source sample rate in Hz. Required when `audio` is
                        `audio/pcm` (the usual case for a live source). WAV
                        reads the rate from its header.
                    channels:
                      type: integer
                      enum:
                        - 1
                        - 2
                      description: >-
                        Number of audio channels. Required when `audio` is
                        `audio/pcm`. Stereo is down-mixed to mono internally.
                    prompt:
                      type: string
                      maxLength: 4096
                      description: >-
                        Custom transcription instruction prepended to the
                        model's system prompt. When omitted, a default prompt is
                        applied.
                    keyterms_prompt:
                      type: array
                      items:
                        type: string
                      description: >-
                        Keyterms that bias the decoder toward specific tokens.
                        Maximum 2048 characters total across all terms. Also
                        accepted as `keyterms` or `word_boost` — provide only
                        one of the three.
                    conversation_context:
                      oneOf:
                        - type: string
                        - type: array
                          items:
                            type: string
                      description: >-
                        Prior turns from the same conversation, in chronological
                        order (oldest first, most recent last), supplied as
                        context so the model transcribes the current clip with
                        greater continuity. Accepts a list of turns or a single
                        string. Oldest turns are dropped first if the context
                        window limit is exceeded.
                    language_code:
                      default: en
                      description: >-
                        Language of the audio as an ISO 639-1 code, or a list of
                        codes for multilingual audio. Ignored when a custom
                        `prompt` is set. Defaults to `en`.
                      oneOf:
                        - type: string
                          enum:
                            - en
                            - es
                            - de
                            - fr
                            - it
                            - pt
                            - tr
                            - nl
                            - sv
                            - 'no'
                            - da
                            - fi
                            - hi
                            - vi
                            - ar
                            - he
                            - ja
                            - ur
                            - zh
                        - type: array
                          items:
                            type: string
                            enum:
                              - en
                              - es
                              - de
                              - fr
                              - it
                              - pt
                              - tr
                              - nl
                              - sv
                              - 'no'
                              - da
                              - fi
                              - hi
                              - vi
                              - ar
                              - he
                              - ja
                              - ur
                              - zh
                    timestamps:
                      type: boolean
                      default: false
                      description: >-
                        Whether to compute per-word `start`/`end` timestamps.
                        When `false` (default), `start`/`end` are omitted from
                        the `words` objects. When `true`, exact timings are
                        computed for each word at an additional latency cost.
                audio:
                  type: string
                  format: binary
                  description: >-
                    Audio bytes, uploaded in chunks as they are produced. Set
                    the part's Content-Type to `audio/pcm` for raw S16LE
                    little-endian PCM (the usual live source) or `audio/wav` for
                    a WAV stream.
            encoding:
              config:
                contentType: application/json
              audio:
                contentType: audio/pcm, audio/wav
      responses:
        '200':
          description: Transcription completed successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SyncTranscriptResponse'
              example:
                text: Hi, I'm calling about my Best Buy order...
                words:
                  - text: Hi
                    confidence: 0.91
                  - text: I'm
                    confidence: 0.88
                confidence: 0.87
                audio_duration_ms: 101567
                session_id: eb92c4ff-4bbb-429f-9b99-7279d7fe738f
                request_time_ms: 243.7
        '400':
          description: >-
            Bad request — audio too short, malformed, invalid config, or a body
            whose `audio` part is not preceded by a `config` part.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DetailErrorResponse'
        '413':
          description: Audio exceeds the 120 s duration or 40 MB size limit.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '415':
          description: Unsupported media type or audio format.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Rate limit exceeded. Retry after `Retry-After` seconds.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DetailErrorResponse'
        '500':
          description: Internal model error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: >-
            Service unavailable — model cold-starting or concurrency cap
            reached.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '504':
          description: Upload went idle too long, or the request exceeded its deadline.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      x-codeSamples:
        - lang: python
          label: Python SDK
          source: >
            from assemblyai.sync.v1 import SyncTranscriber,
            SyncTranscriptionConfig


            transcriber = SyncTranscriber()

            config = SyncTranscriptionConfig(sample_rate=16000, channels=1)


            # Push style, for callback sources (mic, WebRTC, telephony):

            session = transcriber.open_live(config)

            for chunk in microphone():   # your live PCM source
                session.write(chunk)
            session.close()

            print(session.result().text)


            # Or pull style, from an iterable or stream you already have:

            # result = transcriber.transcribe_live(microphone(), config=config)
        - lang: javascript
          label: JavaScript SDK
          source: >
            import { AssemblyAI } from "assemblyai";


            const client = new AssemblyAI({ apiKey:
            process.env.ASSEMBLYAI_API_KEY });

            const config = { sample_rate: 16000, channels: 1 };


            // Push style, for callback sources (mic, WebRTC, telephony):

            const session = client.sync.openLive(config);

            recorder.stdout.on("data", (chunk) => session.write(chunk));

            recorder.stdout.on("end", () => session.close());

            console.log((await session.result()).text);


            // Or pull style, from a stream you already have:

            // const result = await client.sync.transcribeLive(recorder.stdout,
            config);
        - lang: bash
          label: cURL
          source: |
            # cURL cannot overlap with a live recording, but it shows the wire
            # format: a chunked multipart body with the config part first. `rec`
            # streams raw PCM to stdout; the body is assembled and piped in.
            BOUNDARY=aai$(openssl rand -hex 8)
            {
              printf -- "--%s\r\n" "$BOUNDARY"
              printf 'Content-Disposition: form-data; name="config"\r\n'
              printf 'Content-Type: application/json\r\n\r\n'
              printf '{"sample_rate":16000,"channels":1}\r\n'
              printf -- "--%s\r\n" "$BOUNDARY"
              printf 'Content-Disposition: form-data; name="audio"; filename="audio.pcm"\r\n'
              printf 'Content-Type: audio/pcm\r\n\r\n'
              rec -q -t raw -r 16000 -c 1 -b 16 -e signed -
              printf "\r\n--%s--\r\n" "$BOUNDARY"
            } | curl -X POST https://sync.assemblyai.com/v1/transcribe/live \
              -H "Authorization: <YOUR_API_KEY>" \
              -H "X-AAI-Model: universal-3-5-pro" \
              -H "Content-Type: multipart/form-data; boundary=$BOUNDARY" \
              -H "Transfer-Encoding: chunked" \
              --data-binary @-
        - lang: python
          label: Python
          source: |
            import json
            import secrets

            import requests

            boundary = secrets.token_hex(16)
            config = {"sample_rate": 16000, "channels": 1}


            def body(chunks):
                yield (
                    f"--{boundary}\r\n"
                    'Content-Disposition: form-data; name="config"\r\n'
                    "Content-Type: application/json\r\n\r\n"
                    f"{json.dumps(config)}\r\n"
                    f"--{boundary}\r\n"
                    'Content-Disposition: form-data; name="audio"; filename="audio.pcm"\r\n'
                    "Content-Type: audio/pcm\r\n\r\n"
                ).encode()
                for chunk in chunks:  # your live PCM source
                    yield chunk
                yield f"\r\n--{boundary}--\r\n".encode()


            response = requests.post(
                "https://sync.assemblyai.com/v1/transcribe/live",
                headers={
                    "Authorization": "<YOUR_API_KEY>",
                    "X-AAI-Model": "universal-3-5-pro",
                    "Content-Type": f"multipart/form-data; boundary={boundary}",
                },
                data=body(chunks),
                timeout=180,
            )
            response.raise_for_status()
            print(response.json()["text"])
        - lang: javascript
          label: JavaScript
          source: |
            const boundary = crypto.randomUUID().replace(/-/g, "");
            const config = { sample_rate: 16000, channels: 1 };
            const encoder = new TextEncoder();

            const head = encoder.encode(
              `--${boundary}\r\n` +
                'Content-Disposition: form-data; name="config"\r\n' +
                "Content-Type: application/json\r\n\r\n" +
                `${JSON.stringify(config)}\r\n` +
                `--${boundary}\r\n` +
                'Content-Disposition: form-data; name="audio"; filename="audio.pcm"\r\n' +
                "Content-Type: audio/pcm\r\n\r\n"
            );
            const closing = encoder.encode(`\r\n--${boundary}--\r\n`);

            const body = new ReadableStream({
              async start(controller) {
                controller.enqueue(head);
                for await (const chunk of chunks) controller.enqueue(chunk);
                controller.enqueue(closing);
                controller.close();
              },
            });

            const response = await fetch(
              "https://sync.assemblyai.com/v1/transcribe/live",
              {
                method: "POST",
                headers: {
                  Authorization: "<YOUR_API_KEY>",
                  "X-AAI-Model": "universal-3-5-pro",
                  "Content-Type": `multipart/form-data; boundary=${boundary}`,
                },
                body,
                duplex: "half",
              }
            );

            const result = await response.json();
            console.log(result.text);
components:
  schemas:
    SyncTranscriptResponse:
      type: object
      required:
        - text
        - words
        - confidence
        - audio_duration_ms
        - session_id
      properties:
        text:
          type: string
          description: Full transcript of the audio.
        words:
          type: array
          items:
            $ref: '#/components/schemas/Word'
          description: >-
            Per-word confidence scores, plus `start`/`end` timestamps when the
            request sets `timestamps` to `true`.
        confidence:
          type: number
          format: float
          description: Overall transcript confidence (0–1).
        audio_duration_ms:
          type: integer
          description: Duration of the submitted audio in milliseconds.
        session_id:
          type: string
          format: uuid
          description: >-
            Server-generated request identifier. Include this in support
            requests.
        request_time_ms:
          type: number
          format: float
          description: >-
            End-to-end server-side processing time for the request in
            milliseconds, covering queue wait, decoding, and inference.
    ErrorResponse:
      type: object
      properties:
        error_code:
          type: string
          description: Machine-readable error code.
          enum:
            - bad_audio
            - audio_too_short
            - audio_too_large
            - bad_request
            - unsupported_media_type
            - capacity_exceeded
            - service_unavailable
            - inference_timeout
            - inference_error
        message:
          type: string
          description: Human-readable error description.
    DetailErrorResponse:
      type: object
      properties:
        detail:
          type: string
          description: >-
            Human-readable error description (used for auth and rate-limit
            errors).
    Word:
      type: object
      required:
        - text
        - confidence
      properties:
        text:
          type: string
        start:
          type: integer
          description: >-
            Word start time in milliseconds. Present only when the request sets
            `timestamps` to `true` and the word could be aligned; omitted
            otherwise.
        end:
          type: integer
          description: >-
            Word end time in milliseconds. Present only when the request sets
            `timestamps` to `true` and the word could be aligned; omitted
            otherwise.
        confidence:
          type: number
          format: float
  securitySchemes:
    ApiKey:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        Your AssemblyAI API key. Optionally prefixed with `Bearer `. Also
        accepted as the `token` query parameter.

````