Speakr v0.10.16-alpha
In this release, a Tencent Cloud ASR connector is added, request parameters can be set for the text and chat models, dates, times, numbers and file sizes follow the interface language, API tokens count against an account-wide limit, and the recording lists are loaded with a fixed number of database queries.
Security
Thanks to @devkit415 for the reports below, each with a reproduction and a suggested fix.
- CSRF on the token API (#478). Requests from a signed-in browser to
/api/v1and the webhook routes are now required to carry a CSRF token. Requests with an API token are unchanged. - Upload errors (#482). An empty upload, or a file that could not be read as audio, returned HTTP 500 with the FFmpeg output and internal paths. It now returns HTTP 400 with
code: empty_fileorcode: audio_decode_failed. The FFmpeg output is written only to the server log, and the staged copy of the file is removed after every failed upload. This applies to every upload path, including incognito, the share target, and files with a video extension under video retention or video passthrough. - Account-wide API limits (discussion #484). Requests with an API token now also count against an account budget. It applies per endpoint, with a default of twice the per-token limit. An account can hold at most 10 active tokens; creating another one returns HTTP 409 with
code: token_limit_reached. A rate-limited token request is answered with JSON that includes acode. The ASR Voice Recorder and search limits were counted twice per request and are now counted once.
Added
- Tencent Cloud ASR (#427). A connector for Tencent Cloud recording-file recognition, with speaker diarization (
TRANSCRIPTION_CONNECTOR=tencent_asr). When a job is retried, a task already submitted to Tencent or AssemblyAI is resumed, so it is not submitted and billed a second time. Thanks to @i-iooi-i. - Model request parameters.
TEXT_MODEL_EXTRA_BODYandCHAT_MODEL_EXTRA_BODYtake a JSON object that is added to every request to the text or chat model, for example a reasoning setting for OpenRouter orchat_template_kwargsfor llama.cpp. - Shared rate-limit storage. The Redis client is included in the image. With a Redis container and
RATELIMIT_STORAGE_URI=redis://redis:6379/0, the rate limits are counted across all worker processes. Without it, each of the three worker processes counts separately, as before.
Changed
- Interface language (#477, #480, #481). Dates, times, numbers, percentages and file sizes follow the language selected under Account > Interface Language. Flash messages and the verification and password-reset emails are translated. File sizes are shown with at most one decimal, and zero is shown as "0 B". In English, the shares list shows "Today, 4:30 PM".
- Recording lists (discussion #483). The recording list, the inbox, the shared-with-me list, the tag and folder lists and the Shared Transcripts overview are now loaded with a fixed number of database queries, whatever the number of rows. Six indexes are added for these lists.
Fixed
- Register link (#479). The login page showed "Register here" when registration was turned off.
- Search characters (#485).
%,_and\in a search are now matched literally in the recording list, the API v1 recording filter, and the speaker, user and Inquire searches. - Delete all speakers (#475). The voice snippets of the deleted speakers were left in the database. They are now deleted, and snippets left by earlier deletions are removed at startup.
- Duplicate uploads (#476). Two overlapping uploads with the same idempotency key could create two recordings. Only one recording per key is now accepted.
- Incognito video uploads. A video uploaded in incognito mode failed every time.
- Cover art. Under video retention, an MP3 or M4A file with an embedded cover picture was stored as a video.
- Mobile statistics. The silence line read "12.5% % of audio".
Dependencies
- Flask-Limiter 3.5.0 → 4.1.1, with redis 7.4.1 (new).
- Markdown 3.5.1 → 3.11.1, scikit-learn 1.3.0 → 1.9.1, Babel 2.12.1 → 2.18.0, Flask-WTF 1.2.2 → 1.3.0, email-validator 2.2.0 → 2.3.0, python-docx 1.1.0 → 1.2.0, python-dotenv 1.2.2 → 1.2.4, pytz 2024.1 → 2026.5, tzdata 2025.2 → 2026.5.
- Full image: Pillow 12.3.0 → 13.0.0, filelock 4.1.1 → 4.2.2.
- FFmpeg (lite image) n8.1.3-18 → n8.1.3-24. setuptools is removed from the base image.
- GitHub Actions updated.
Upgrading
Pull the new image and start as usual. At startup, one column is added to the processing jobs, a unique index on the upload idempotency key and six indexes for the lists are created, and orphaned speaker snippets are removed. Where two recordings of a user share an idempotency key, the key is cleared on the older one.
- An account that already holds more than 10 active tokens keeps them. New tokens are refused until the count is below the limit.
- API clients: an upload that cannot be read now returns HTTP 400 (was 500), and a rate-limited token request returns JSON.
- New optional settings:
API_USER_RATE_LIMIT_READ,API_USER_RATE_LIMIT_WRITE,API_USER_RATE_LIMIT_PROCESS,API_MAX_TOKENS_PER_USER(default 10,0for no limit),RATELIMIT_STORAGE_URI,TEXT_MODEL_EXTRA_BODY,CHAT_MODEL_EXTRA_BODY, and theTENCENT_*settings of the Tencent connector.
Full Changelog: v0.10.15-alpha...v0.10.16-alpha