Your server, your key
Karelia Translate runs on your own Flarum server and talks only to the translation service you choose, with your own key. It never contacts us, and with a local model or LibreTranslate no text leaves your server at all.
Where your data goes
On your own server, and to the translation service you choose. When a reader asks for a translation, the text of that post (and for the first post its title) is sent to that service with your API key. Code blocks, inline code, web addresses, @mentions and your "never translate" words are replaced by placeholders first, so they are never sent. With a local model or a self-hosted LibreTranslate server, nothing leaves your server. The extension never contacts Karelia Labs: it has no telemetry, no analytics, no license server and no account with us.
What is stored
Everything the extension stores is in your own Flarum database and cache.
| Data | Where and why | How long |
|---|---|---|
| Language of each post (a code such as sv) | Database, posts table. Shows the translate link only on posts in another language | As long as the post exists |
| Saved translations: post id, languages, a hash of the original text, the service, the translated title and text, characters, time | Database, karelialabs_translations. Shows a translation again without asking the service | Deleted with the post |
| Settings: service, address, model, limits, glossary, and the API key unless it is set as an environment variable | Database, settings table. Runs the extension | Until an administrator changes them |
| Monthly usage: the month and the number of characters sent | Database, settings table. The monthly limit | Reset every month |
| Hourly counter: a one-way hash of the member id, or of a guest's IP address, and a count | Flarum's cache. The limit per reader per hour | One hour |
Personal data
The extension adds no profile data. Posts and titles may contain personal data written by members; their text is sent to your translation service when a reader asks, and the translation is saved in your database. The hourly limit keeps a one-way hash of the member id, or of a guest's IP address, for one hour. Your forum is the controller of this data, and the translation service you choose processes it under your agreement with that service.
Permissions
The extension adds one Flarum permission and checks it on the server for every translation.
| Permission | Why the app needs it |
|---|---|
| Translate posts | Who may ask for translations. Members by default; guests only if you give it to them. Readers without it never see the link |
| Administrator | Only administrators can see the settings, read the usage or run the connection test. The extension adds no other access |
Access control
Every translation request is checked against the Translate posts permission and against the reader's right to see the post, so a reader cannot translate a post they cannot read. The connection test and the settings are available to administrators only. API keys never reach readers' browsers; administrators see them in the settings like any other Flarum setting. Error messages from services are shown without the key.
Untrusted input
Post text is untrusted input. Translations from a service are treated as untrusted too: they are parsed and rendered by Flarum's own formatter with the post author's rights, exactly like a post, so a service cannot inject markup that the author could not have written. Placeholders are put back after translation. If a service drops one, the extension logs a warning with the post id, so an administrator can see it.
Dependencies
The extension depends on Flarum and on the official Anthropic PHP SDK (MIT license), installed by Composer. The other services are called with Guzzle, the HTTP client Flarum already includes, with a time limit on every request. The forum and admin scripts are built with Flarum's standard tooling and bundle no third-party code.
Other points
API keys
Keys are stored in Flarum's settings table, or kept out of the database entirely with environment variables (for example KARELIA_TRANSLATE_DEEPL_KEY), which win over the setting.
Translation services
Each service processes text under its own terms. DeepL, Google, Anthropic and OpenAI-compatible providers receive only the text of the posts that readers ask to translate, and only as long as you use them.
Logging
The extension writes nothing to logs during normal use. When a service fails, its error message goes to Flarum's log without the API key. When a service drops a protected part, a warning with the post id and the number of parts is logged. Post text is never logged.
Sub-processors
None. We receive no forum data, so there is nothing to pass on. The translation service is chosen and contracted by you. Subscriptions and payments are handled by Floxum and its payment provider. For the other parties involved in our own support and bookkeeping, see the privacy policy.
AI and language models
The extension contains no language model of its own. If you choose Anthropic or an OpenAI-compatible service, post text is translated by that model under your agreement with the provider. With a local model, it runs on your own hardware. DeepL, Google and LibreTranslate are machine translation services.
Vulnerabilities
Report a suspected vulnerability to support@karelialabs.atlassian.net. Please include what you found, how to reproduce it and which version is affected, and give us a reasonable time to fix it before you publish details. We read every report.
Deleting data
Saved translations are deleted together with their post. Disabling the extension keeps its data. Run php flarum migrate:reset --extension=karelialabs-translate before removing the package to drop the table and the language column. Settings, including a stored API key, stay until an administrator clears them.