Where does Jitsi save transcripts and how do I download them?

Short answer

Jigasi saves complete transcripts when its transcription session ends, if a file publisher is enabled. Stock Docker stable-11146 through stable-11248 stores them under ${CONFIG}/storage/transcripts, while package defaults use /var/lib/jigasi/transcripts. Docker's /transcripts route serves known file URLs without a meeting permission check, so block it or add authenticated delivery. The bridge proxy can capture final messages as JSONL dumps, with separate storage and retention. [S1][S2][S3][S4][S9]

Who this is for

Use this after captions work and you need a retained file or controlled delivery. Follow the existing Vosk setup or bridge guide for recognition. Client caption options and server file saving have separate controls. [S3][S9][S11][S12]

How it works

Jigasi’s SAVE_TXT and SAVE_JSON enable complete file publishers. SEND_JSON sends live results for captions; SEND_TXT sends recognized speech into meeting chat. Neither emails a completed file. BASE_URL constructs advertised links; it does not create a web server. [S3]

Saved names follow DIRECTORY/<UTC-Instant>_<UUID>/transcript_<UTC-Instant>_<UUID>.txt, or .json. Directory and filename identifiers differ. Each format has its own publisher and generated directory, so both formats need not share one folder. Files appear when the transcription session ends. [S3]

TXT contains meeting details, participant names, UTC speech timestamps and meeting events. JSON retains structured events, alternatives and metadata, which can include email or identity fields. Both use UTF-8 and retain final speech results, not interim revisions. [S3]

Installation Host folder Inside transcriber
Stock Docker stable-11031, before rootless ${CONFIG}/transcripts /tmp/transcripts
Stock Docker stable-11146 through stable-11248 ${CONFIG}/storage/transcripts /tmp/transcripts
Released Debian/Ubuntu Jigasi /var/lib/jigasi/transcripts Same host path

The Docker move shipped with rootless PR #2258 in stable-11146. Web mounts the current folder read-only at /usr/share/jitsi-meet/transcripts. Existing custom DIRECTORY=/config/transcripts configurations use their own path; check their mounts instead of assuming this table applies. [S1][S2][S3]

Before you start

Checked October 6, 2026: Docker’s latest release remains stable-11248. Package steps cover Jigasi 1.1-415-g2750d54-1. Keep Compose files and images from one release, preserve recognition/XMPP settings, and schedule recreation without active meetings. [S1][S6][S10]

Obtain participant agreement for retention and delivery. Choose who can retrieve files and when copies expire. For S3, prepare a private bucket and credentials restricted to the archive prefix. No real credentials belong in this guide or your repository. [S3][S8]

Steps

  1. Docker stable-11248: protect downloads first. Set CONFIG to your actual .env value. These commands use its handbook default. Keep existing backend overlays in the helper. [S1][S4][S10]

    Terminal
    CONFIG="$HOME/.jitsi-meet-cfg"
    mkdir -p "${CONFIG}/storage/transcripts" "${CONFIG}/web/nginx-custom"
    sudo chown 1000:1000 "${CONFIG}/storage/transcripts"
    sudo chmod 750 "${CONFIG}/storage/transcripts"
    dc() {
        docker compose -f docker-compose.yml -f transcriber.yml "$@"
    }

    Save this as ${CONFIG}/web/nginx-custom/transcripts-private.conf, a filename chosen here. Startup copies it into the included runtime directory. These rules override the stock static-file regex: [S4][S10]

    Nginx
    location = /transcripts { return 403; }
    location ^~ /transcripts/ { return 403; }

    Run dc up -d --force-recreate web, then dc exec -T web nginx -t -c /run/web/config/nginx/nginx.conf. This blocks participant download links too. Deliver through your authenticated application with meeting-specific authorization, or an administrator, rather than removing protection. [S4][S10]

  2. Docker stable-11248: enable files. In .env, set JIGASI_TRANSCRIBER_ENABLE_SAVING=1 and JIGASI_TRANSCRIBER_ADVERTISE_URL=false. Append these assignments to ${CONFIG}/transcriber/custom-sip-communicator.properties, preserving existing entries and avoiding conflicting duplicates: [S1][S5]

    Properties
    org.jitsi.jigasi.transcription.DIRECTORY=/tmp/transcripts
    org.jitsi.jigasi.transcription.SAVE_TXT=true
    org.jitsi.jigasi.transcription.SAVE_JSON=true
    org.jitsi.jigasi.transcription.SEND_JSON=true
    org.jitsi.jigasi.transcription.SEND_TXT=false

    Make the custom file readable by UID 1000. Run dc config --quiet and dc up -d --force-recreate transcriber. At session end, administrators can retrieve generated files directly from host storage. Without protection, the URL is ${PUBLIC_URL}/transcripts/<generated-directory>/<generated-filename>; hiding its advertisement is not access control. [S1][S3][S4][S5][S10]

  3. Docker stable-11248: optional S3 hook. PR #2225 closed without merging on June 7, 2026. Its proposed hook environment variables are unavailable in this release. Use custom properties and an executable script instead. The hook receives one absolute transcript-directory argument, once per publisher; Jigasi does not wait, retry or check its exit status. [S5][S7]

    Run mkdir -p "${CONFIG}/transcript-hooks", then save this example as ${CONFIG}/transcript-hooks/upload-s3.sh. Replace amzn-s3-demo-bucket with your private bucket. It uploads only TXT/JSON, records its own result and retains local files. [S7][S8][S10]

    Terminal
    #!/bin/sh
    set -eu
    umask 077
    dir=${1:?Missing transcript directory}
    exec >>"$dir/s3-upload.log" 2>&1
    found=false
    for file in "$dir"/*.txt "$dir"/*.json; do
        [ -f "$file" ] || continue
        found=true
        if aws s3 cp "$file" "s3://amzn-s3-demo-bucket/jigasi/$(basename "$dir")/" --only-show-errors; then
            :
        else
            printf '%s\n' 'S3 upload failed'
            exit 1
        fi
    done
    [ "$found" = true ] || { printf '%s\n' 'No saved transcript found'; exit 1; }
    printf '%s\n' 'S3 upload completed'

    Run chmod 755 "${CONFIG}/transcript-hooks" "${CONFIG}/transcript-hooks/upload-s3.sh". Stock Jigasi lacks AWS CLI. Save this example as Dockerfile.transcript-s3: [S5][S8][S10]

    dockerfile
    FROM ghcr.io/jitsi/jigasi:stable-11248
    USER root
    RUN apt-dpkg-wrap apt-get update \
        && apt-dpkg-wrap apt-get install -y --no-install-recommends awscli \
        && apt-cleanup
    USER s6

    Build with docker build -f Dockerfile.transcript-s3 -t jigasi-transcript-s3:stable-11248 .. Provision an existing protected shared-credentials file at ${CONFIG}/transcript-aws/credentials, outside Git, readable by UID 1000 with mode 600. Save this as transcript-s3.yml; set your bucket region: [S5][S8][S10]

    YAML
    services:
      transcriber:
        image: jigasi-transcript-s3:stable-11248
        environment:
          AWS_SHARED_CREDENTIALS_FILE: /opt/transcript-aws/credentials
          AWS_DEFAULT_REGION: us-east-1
        volumes:
          - ${CONFIG}/transcript-hooks:/opt/transcript-hooks:ro
          - ${CONFIG}/transcript-aws/credentials:/opt/transcript-aws/credentials:ro

    Append to the same custom properties file: [S7]

    Properties
    org.jitsi.jigasi.transcription.EXECUTE_SCRIPTS=true
    org.jitsi.jigasi.transcription.SCRIPTS_TO_EXECUTE_LIST=/opt/transcript-hooks/upload-s3.sh
    org.jitsi.jigasi.transcription.SCRIPTS_TO_EXECUTE_LIST_SEPARATOR=,

    Add -f transcript-s3.yml to dc, validate, then recreate transcriber. An IAM role is another credential route; containers need working metadata access if relying on an instance role. Never bake keys into the image. [S8][S10]

  4. Debian/Ubuntu Jigasi baseline: enable storage and the same hook. [S3][S6][S10]

    Terminal
    sudo install -d -o jigasi -g jitsi -m 750 /var/lib/jigasi/transcripts

    Edit /etc/jitsi/jigasi/sip-communicator.properties: use step 2’s flags, with org.jitsi.jigasi.transcription.DIRECTORY=/var/lib/jigasi/transcripts and org.jitsi.jigasi.transcription.ADVERTISE_URL=false. Packages do not create Docker’s download route. [S3][S6]

    For uploads, use the official system installer: [S8][S10]

    Terminal
    curl -fsSL https://awscli.amazonaws.com/v2/install.sh | sudo bash -s -- --system

    Save the same script locally as upload-s3.sh, then run sudo install -m 755 upload-s3.sh /usr/local/bin/jitsi-transcript-upload-s3. Configure credentials for service user jigasi, not just your SSH login. Use step 3’s hook properties with that absolute script path. Run sudo systemctl restart jigasi during maintenance. [S6][S7][S8][S10]

  5. Bridge proxy 6747f187: capture separately. Add to your existing opus-transcriber-proxy service, retaining the bridge guide’s session-ID configuration: [S9][S11]

    YAML
    environment:
      DUMP_TRANSCRIPTS: "true"
      DUMP_BASE_PATH: /data
    volumes:
      - ${CONFIG}/storage/bridge-transcripts:/data:Z

    Run mkdir -p "${CONFIG}/storage/bridge-transcripts" and make it writable by the proxy’s actual runtime user. Its image does not declare Jitsi’s UID 1000. Recreate the proxy. Final messages become /data/<sessionId>/transcript.jsonl, one JSON object per line with capture timestamp and full message. This documented debug capture has no automatic cleanup or Jigasi download-link delivery. Keep it outside web-served storage. [S9][S10]

  6. Both paths: retain and delete deliberately. Example Docker candidates older than 30 days: [S10]

    Terminal
    find "${CONFIG}/storage/transcripts" -type f -mtime +30 -print

    Check upload success and your policy before replacing -print with -delete. Use the corresponding package/bridge directory separately. Configure S3 lifecycle expiration too, including noncurrent versions where versioning is enabled. Deleting local files does not remove S3 objects, backups or cached downloads. [S8][S10]

Configuration reference

Jigasi rows below use the exact prefix org.jitsi.jigasi.transcription. in properties files. Docker appends custom properties after its generated settings. [S3][S5][S7]

Setting Default: released code / stock Docker Purpose
DIRECTORY /var/lib/jigasi/transcripts / /tmp/transcripts Saved files. [S3][S1]
BASE_URL http://localhost/ / ${PUBLIC_URL}/transcripts Advertised URL base. [S3][S1]
SAVE_TXT, SAVE_JSON false, false / true, false Complete file formats. [S3][S1]
SEND_TXT, SEND_JSON false, true / same Live chat/captions. [S3][S1]
ADVERTISE_URL false / false Announce saved-file links. [S3][S1]
EXECUTE_SCRIPTS false / no mapping Enable hook. [S7]
SCRIPTS_TO_EXECUTE_LIST script/example_handle_transcript_directory.sh / no mapping Executable paths; explicitly override. [S7]
SCRIPTS_TO_EXECUTE_LIST_SEPARATOR , / no mapping Java regex delimiter; avoid spaces around list entries. [S7]
JIGASI_TRANSCRIBER_ENABLE_SAVING Docker .env: 1 Emit saving block. [S1]
JIGASI_TRANSCRIBER_ADVERTISE_URL, JIGASI_TRANSCRIBER_SEND_TXT Docker .env: false, false Map corresponding properties. [S1]
CONFIG, PUBLIC_URL Docker .env: ~/.jitsi-meet-cfg, setup-specific Storage root and external URL. [S1]
location, return Web custom Nginx config: no block by default Example disables transcript downloads. [S4][S10]
AWS_SHARED_CREDENTIALS_FILE, AWS_DEFAULT_REGION AWS CLI environment: ~/.aws/credentials, unset region Example selects private credentials and bucket region. [S8]
DUMP_TRANSCRIPTS, DUMP_BASE_PATH Proxy environment: false, /tmp Optional JSONL capture. [S9]

Common mistakes

Jigasi’s README says TXT saving defaults on, but released code defaults off. Docker explicitly enables TXT. A custom directory from an older setup can override the new storage mapping. Changing generated /run/jigasi/config/sip-communicator.properties disappears on recreation. [S1][S3][S5][S12]

JIGASI_TRANSCRIBER_ENABLE_SAVING=0 omits Docker’s saving block, allowing code defaults to disable files unless custom flags enable them again. For explicit disablement, set both saving properties false. Startup still checks /tmp/transcripts write access. [S1][S3][S5]

Verify

Finish a test transcription session after speaking a unique sentence. Run dc logs --tail=100 transcriber and: [S3][S10]

Terminal
find "${CONFIG}/storage/transcripts" -type f \( -name '*.txt' -o -name '*.json' \) -print
TRANSCRIPT_FILE=$(find "${CONFIG}/storage/transcripts" -type f -name '*.txt' -print -quit)
TRANSCRIPT_PATH=${TRANSCRIPT_FILE#"${CONFIG}/storage/transcripts/"}
[ -n "$TRANSCRIPT_FILE" ] && curl -sS -o /dev/null -w '%{http_code}\n' \
    "https://meet.example.com/transcripts/${TRANSCRIPT_PATH}"

Expect the exact log prefix Wrote final transcript to followed by the generated path. Open the actual file and confirm your sentence. The known-file HTTP check must print 403; test every public entry point, including the origin if using a CDN. For S3, require your hook’s S3 upload completed log and verify the actual object with aws s3 ls s3://amzn-s3-demo-bucket/jigasi/ --recursive, using your bucket. [S3][S8][S10]

For bridge dumps, check the log prefix Transcript dump enabled: and inspect the generated JSONL with jq -r '.message.transcript[].text' transcript.jsonl. This command assumes you have copied the actual dump to that local filename. Check final words, participant IDs and persistence after recreation. [S9]

If it still fails

Look for Unable to write transcript to file , Was unable to make a directory called or Could not execute in transcriber logs. Package logs are /var/log/jitsi/jigasi.log. Inspect ownership, effective custom properties, CLI availability, credentials and each directory’s s3-upload.log. There is no built-in upload retry; rerun the script against a failed directory after fixing the cause. [S3][S6][S7][S8]

For missing speech or XMPP errors, use transcription troubleshooting. [S11]

FAQ

Does SEND_TXT send the transcript file to participants?

It sends recognized speech to meeting chat. File delivery requires a separate authenticated download or your application workflow. [S3]

Can I save captions from an embedded meeting?

Stable-11248 exposes transcriptionChunkReceived with { data }; final text is data.final, while data.stable is still interim. Capture final messages in your app and handle reconnection, deduplication and permission checks. [S9][S12]

Does the bridge replacement save the same TXT file?

No. Its optional dump is JSONL of final provider messages, not Jigasi’s complete transcript format or an automatic download service. For managed delivery, see our transcription setup service. [S9][S11]

Sources

All checked 2026-10-06.

[S1] Latest release, current transcriber, web volumes, transcription template, Docker handbook, stable-11248 released 2026-09-14, release note/source code/official doc.

[S2] stable-11031 overlay, old web volumes, rootless PR #2258, stable-11146, 2026-08-03 release, source code/release note.

[S3] Released Jigasi flags, publisher, TXT, JSON, final filter, session end, 2026-09-11 snapshot, source code.

[S4] Docker Nginx route, web config copy, Nginx launch, stable-11248, source code.

[S5] Docker custom properties, Jigasi image, apt wrapper, cleanup, stable-11248, source code.

[S6] Jigasi package index, installed paths, ownership, service, package 1.1-415, official repository/source code.

[S7] Script invocation, source code; Docker PR #2225, closed 2026-06-07, unmerged proposal.

[S8] AWS upload, listing, CLI installation, CLI environment, roles, container metadata, public-access blocking, lifecycle, Debian awscli, official docs/package index.

[S9] Bridge proxy dump documentation, capture code, image, 2026-10-05 snapshot; Meet caption event, payload, source code/official doc.

[S10] Docker CLI, Nginx location, return, switches, coreutils, find, systemctl, curl, shell, official docs.

[S11] jitsi.help Vosk, bridge, troubleshooting, service, independent guides.

[S12] Meet client configuration, event test, stable-11248; Jigasi README, 2026-09-11 snapshot, source code/official repository docs.

Open questions

Real meeting saves, the derived AWS image, end-to-end S3 delivery and proxy restart persistence need server testing. No stock hook retry, per-meeting download authorization, or automatic bridge TXT export was verified. Test custom routing and purge any previously cached public transcript copies. [S3][S4][S7][S8][S9]

Recently updated