Subprocessors — Emet translation platform
Last verified against the running production system: 2026-08-07.
Emet uses a small number of third-party services to operate. This page lists every one that can receive Customer Content — your source documents, translations, translation memory, glossaries or style guidance — or personal data about your users, and states exactly what each one receives. Services that only ever see infrastructure telemetry are listed too, so the list is complete rather than convenient.
Where a claim can be checked in the software, the source is named. This is deliberate: it lets your reviewer verify rather than take our word for it.
Summary
| # | Subprocessor | Purpose | Receives Customer Content? | Location |
|---|---|---|---|---|
| 1 | Hostinger International Ltd. | Hosting — the server the platform runs on | Yes — all of it, at rest | São Paulo, Brazil |
| 2 | Anthropic PBC | AI drafting and AI quality review | Yes — segment text, in transit | United States |
| 3 | Google LLC (Gemini API) | AI drafting — all target languages (§3) | Yes — segment text, in transit | United States |
| 4 | Backblaze Inc. (B2) | Off-site backup | Encrypted only — full backups plus continuous transaction logs, unreadable to them | United States (us-east-005) |
| 5 | Functional Software, Inc. (Sentry) | Error tracking | Incidentally — see §5 | European Union |
| 6 | Let's Encrypt / ISRG | TLS certificates | No — hostnames only | United States |
| 7 | UptimeRobot | Availability monitoring | No — see §7 | United States |
| 8 | Healthchecks.io | Backup monitoring | No — see §8 | United States |
| 9 | Paddle | Payments — Merchant of Record | No — but holds buyer identity and payment data, see §9 | United Kingdom, or United States for US buyers |
Transactional email involves no third party. Invitations, password resets and notifications are sent by our own mail server on the same host in São Paulo, from noreply@hesedtranslation.com. No email provider sees your users' addresses.
No other third party receives Customer Content. In particular, the semantic search that powers translation-memory matching runs a model locally on our own server (EMBEDDING_BACKEND=sentence_transformers); your text is not sent to any embedding or vector-search provider.
1. Hostinger International Ltd. — hosting
Location: São Paulo, Brazil. What they hold: everything.
The entire platform — application, PostgreSQL database and object storage — runs on a single virtual private server. All Customer Content is stored there: source files as uploaded, every segment, every translation version, translation memory, glossaries, and user accounts.
Encryption at rest: yes, on both deployments. The database, object store and cache live inside a LUKS2 volume (AES-XTS, 512-bit key) — a separate container for app.emet.ing and for app.hesedtranslation.com, so the two can be moved or destroyed independently.
What the encrypted case actually protects. The key is held on the server, so the protection is against the disk leaving the building — decommissioned, removed, or seized — and not against compromise of the running host, which by definition can read its own storage. That is worth stating precisely because cloud-provider encryption elsewhere in this industry has exactly the same limit; a running instance reads plaintext there too. Access is otherwise controlled by the operating system and the application's own authorisation, and all network access is encrypted in transit (TLS, certificates from §6).
Data residency consequence: your primary copy is in Brazil. The backup copy is in the United States (§4), and AI processing happens in the United States (§2, §3). If your agreement requires content to remain within a single jurisdiction, that is not what this architecture does today, and it needs to be raised before signing rather than after.
2. Anthropic PBC — AI drafting and quality review
Location: United States. Receives: source segment text and, for quality review, your translation.
Anthropic's Claude models produce the first-pass draft of each segment and, when you run the AI language check, review the draft against the source.
What is sent, per segment:
- the source sentence to be translated;
- a small window of neighbouring sentences from the same document, for context;
- your project's glossary terms that match the segment;
- your project's style profile and any translation guidelines attached to the project;
- for quality review only, the current translation of the segment.
What is not sent: the name or email of any user, your organisation's name, project or file names, rates, invoices, or any account data. The request carries the text to be translated and the rules for translating it, nothing else. (See api/app/services/prompt.py for how the request is assembled, and api/app/services/qa_llm.py for the review request.)
Frequency: on pre-translation of a file, on a single-segment AI draft request, and on an AI quality-check run. It does not happen in the background and it does not happen on reading or editing.
Data use and retention — read on 2026-09-07 from Anthropic's own terms. We use Anthropic under their Commercial Terms (effective 2025-06-17). Those Terms govern the use of Anthropic API keys and state expressly that the services are not for consumer use — Anthropic's consumer products are covered by separate Consumer Terms. Because we hold an API key and call the API directly, the commercial footing is not a setting anyone could get wrong; it follows from which product we use. They state that Anthropic may not train models on customer content from the services, and Anthropic's platform documentation adds that retained data is never used for model training without express permission. Verified 2026-09-07 that the production key authenticates against Anthropic's API and the account is in good standing.
Retention, stated precisely rather than glossed: API inputs and outputs are deleted within 30 days of receipt or generation by default. If Anthropic's trust-and-safety systems flag a request, that is not the whole story: flagged inputs and outputs may be kept up to 2 years, and the resulting classification scores up to 7 years. We would rather you knew that than discovered it.
A model-specific point in our favour, for now. Anthropic designates some models “Covered Models” that require 30-day retention and cannot use a zero-retention arrangement. The models Emet uses — Sonnet 4.6 and Haiku 4.5 (api/app/config.py) — are not on that list today. If the platform ever moves to a Covered Model, this paragraph changes with it.
Cost and volume are recorded. Every call is written to a model_calls row with its token counts and cost, so what was sent and when is auditable from your own organisation's spend page rather than taken on trust.
Turning it off: AI quality review is a per-project switch (qa_llm_enabled). AI drafting is what the platform is for; a project that must not use it should not be pre-translated, and we should agree that in advance.
3. Google LLC (Gemini API) — AI drafting
Location: United States. Receives: the same per-segment payload as §2.
Some drafting is routed to Google's Gemini model instead of Anthropic's. Which languages is controlled by a single setting, GEMINI_TARGET_LANGS.
*That setting is `` — every target language.** Whatever language your projects translate into, segments on the cheap path go to Google. This is a live subprocessor, not a possibility.
It was pt-BR until 2026-09-08, when it was widened to all languages. Brazilian Portuguese was the pair we could measure: a 400-segment benchmark against real draft-and-human-final pairs put Gemini ahead of the comparable Anthropic model there.
⚠️ WHAT CHANGED ON 2026-09-08, AND WHY
Google previously received segment text only from projects translating into Brazilian Portuguese. It now receives it from projects in every target language. No new company joined this list — Google was already on it — but what Google receives is wider, and we count that as a subprocessor change, because what matters to you is whose systems hold your text, not how many names are printed on this page.
The part that does not flatter us. The pt-BR benchmark is the only valid measurement we have. We attempted the same comparison for Arabic and threw the result away: the reference translations turned out to be AI drafts a reviewer had confirmed without editing, so the comparison was circular. We extended to the other languages on the judgement that one uniform route is a more honest starting point than a single measured exception — not on evidence that Gemini is better for your language, which we do not have. The platform records per-language editing effort, and any language the data turns against can be returned to the previous provider on its own.
If this is not acceptable for your organisation, say so and we will exclude your target languages. That is a per-language setting, not an all-or-nothing one.
This change was made without the 30 days' notice that DPA §6 and Terms §9 promise, because on 2026-09-08 there was nobody to notify: those documents were unsigned drafts and no organisation was contracted under them. That will not be true of the next change, so the procedure is written down here rather than left to memory.
How we give that notice. We email each organisation's administrator, add a dated entry to this list, and count the 30 days from the email. If you object on reasonable data-protection grounds and we cannot resolve it, you may terminate the affected service and export your content under Terms §7. A replacement made urgently for security or continuity reasons may be notified promptly after the fact (DPA §6).
What sets the clock running is a new provider API key reaching production. That is the moment a subprocessor becomes real, and it is listed as a maintenance trigger in legal/README.md so the notice is not remembered but looked up.
Data use and retention — read on 2026-09-10 from Google's own terms. We use the Gemini API on its paid tier, which matters: the Gemini API Additional Terms of Service treat the paid and free tiers differently, and only the paid tier carries the undertaking below. On the paid tier Google states that it does not use your prompts or responses to improve its products, and that it processes them under its Data Processing Addendum for Products Where Google is a Data Processor. Prompts and responses are logged for detecting prohibited use and keeping the service secure, and for no other purpose. The production key was verified against the paid tier — a free-tier key would silently place your segments under terms that permit product improvement, which is why the requirement is written into api/app/config.py rather than left to memory.
Whatever the setting, one thing does not change: the careful-model rule sends every segment containing a Scripture reference, and every verse or quotation, to Anthropic. Google is only ever used for ordinary prose.
Paid tier, deliberately. Under Google's terms for unpaid services, prompts and responses are used to improve Google products and may be read by human reviewers. Under paid-tier terms they are not used to improve products and are retained only briefly for abuse detection. Because we process unpublished client Scripture, the platform is configured against a billing-enabled account, and the requirement is recorded in the software's own configuration with the date it was verified (api/app/config.py, verified 2026-08-09 against the live key). We consider free-tier use of this API incompatible with handling your content.
4. Backblaze Inc. (B2) — off-site backup
Location: United States, bucket region us-east-005. Receives: a nightly full copy of everything, plus continuous database transaction-log segments and periodic physical database snapshots — all encrypted.
Every night the platform takes a full PostgreSQL dump and archives the object store — which is to say, your source documents, translations, translation memory and glossaries — and uploads both to Backblaze B2.
Since 2026-09-09 that is no longer the whole picture, and the difference is worth stating rather than folding into "backups". The database's transaction log — the running record of every change as it happens — is archived to the same bucket continuously, alongside periodic physical snapshots of the database that the log replays against. This is what allows recovery to a chosen moment rather than only to the last nightly copy, and it narrows how much recent work a failure could destroy from up to a day to minutes. It also means Backblaze receives your content more or less as you produce it, instead of once a night. The category of data is unchanged — it is the same database, the same documents and translations — and every object is encrypted before it leaves the server on exactly the same terms.
All three kinds are kept for 14 days, after which they are deleted automatically.
Encryption: every archive is encrypted by us, on our server, before it is uploaded (age; infra/scripts/backup.sh, wal-archive.sh, basebackup.sh). Backblaze therefore holds opaque blobs. This is not a promise about their key management — it is a statement that their key management is irrelevant to your content, because what they store cannot be read without a key they do not have.
Where that key is. The server holds only the public half, so the machine can encrypt a backup but cannot decrypt one. The private key is held off-site by the operator and exists nowhere on the server or in its configuration. Two consequences worth stating plainly, because they cut in both directions:
- An attacker who takes the server, or the backup bucket, or both, gets nothing readable.
- If the operator loses that key, the backups are permanently unrecoverable. We hold it in a password manager and have rehearsed a full restore using only the off-site copy, with the server treated as destroyed. On 2026-09-09 we also rehearsed recovery to a chosen moment in time from the real encrypted archives, verifying that a change made before that moment survived and one made after it did not.
Uploads are additionally over TLS, and Backblaze applies their own server-side encryption on top; neither is what protects your content here.
Consequence for deletion: when you delete content, or when your organisation is deleted, it is removed from the live system immediately (§ Privacy Policy, "Deletion") but persists in backups until the 14-day window rolls past. We cannot surgically remove a single record from a backup archive without invalidating the backup. Fourteen days is the maximum lag.
5. Functional Software, Inc. (Sentry) — error tracking
Location: European Union (Sentry's EU data region, de.sentry.io). Receives: software errors.
Moved from the United States on 2026-09-10, for both deployments, and the reason is worth stating because it is the only thing in this list that moved for a legal rather than a technical reason. The ANPD recognised the European Union as adequate on 26 January 2026 (Resolution CD/ANPD nº 32/2026), so error reports now land in a territory Brazil accepts without further mechanism — where before they went to a country it does not. Sentry organisations cannot be migrated between regions, so this was a new organisation rather than a migration. Verified on both stacks by sending a test event and confirming the transport host.
The United States organisation was then closed, on 2026-09-12. The error history it held was not carried across and no longer exists — which is the point worth having: this is not merely a change of destination going forward, with an old store of reports still sitting in a country the ANPD has made no adequacy finding about. Sentry holds nothing of ours in the United States.
When the platform hits an unhandled error, a report is sent to Sentry so it can be diagnosed and fixed. Reports contain the error, the code path, and the request's method and URL.
Configured to minimise what is sent: personal-data capture is switched off (send_default_pii=False) and performance tracing is off entirely (traces_sample_rate=0.0), so no request bodies, headers or user identities are attached by default — see api/app/observability.py.
Why this row still says "incidentally" rather than "no": an error report includes the URL of the failing request, and some URLs contain record identifiers. Those identifiers are opaque (UUIDs), not names or text. It remains theoretically possible for an exception message to quote a fragment of data that caused it. We cannot promise zero Customer Content in error reports; we can say that none is sent deliberately and that the collection is configured as narrowly as the tool allows.
6. Let's Encrypt / Internet Security Research Group — TLS certificates
Location: United States. Receives: hostnames only.
Issues and renews the certificates that encrypt traffic to the platform's hostnames — today app.hesedtranslation.com and app-files.hesedtranslation.com, and, once the Emet deployment is live, emet.ing, app.emet.ing and files.emet.ing. Certificates are public by nature (they appear in Certificate Transparency logs). No customer data of any kind is transmitted.
7. UptimeRobot — availability monitoring
Location: United States. Receives: nothing but the result of a request.
Checks every five minutes, from outside our infrastructure, that the platform is answering: the readiness endpoint /api/readyz, the application's front page, and the object store's health endpoint. It records the HTTP status code and the response time.
Why it receives no Customer Content: the readiness endpoint reports only whether the database, cache and object store answered, and how many milliseconds each took. It reads no customer data and returns none. The other two checks fetch a page and a health path that require no authentication and contain no customer data.
It exists because the alternative is finding out from you that the platform is down. Our own on-server watchdog cannot report a server that has stopped answering — only something outside can.
8. Healthchecks.io — backup monitoring
Location: United States. Receives: a signal that the nightly backup ran, and that run's log output.
Every other check we have reports a backup that ran. None reports one that did not — a removed schedule or a full disk simply stops producing log lines, which is indistinguishable from a log nobody has read. This service expects a signal each night and raises an alarm when one does not arrive.
What the log contains: file sizes, object counts, timing, and the storage key of the archive (a date-stamped filename). It does not contain your documents, your translations, or any part of the backup's contents — the backup itself goes to Backblaze (§4), encrypted, and never passes through here.
9. Paddle — payments (Merchant of Record)
Location: United Kingdom — or the United States, for buyers based there. Receives: buyer identity and payment data. No Customer Content.
*Which Paddle entity you contract with depends on where you are*, not on where we are, and it is worth stating precisely because it changes which country your payment data sits in. Paddle's Master Services Agreement (definition 1.1, read 2026-09-09) sets it:
| If you are | Your contract is with | Registered at |
|---|---|---|
| in the United States | Paddle.com Inc | 3811 Ditmars Blvd, #1071, Astoria, New York, 11105-1803, USA |
| anywhere else | Paddle.com Market Ltd | 30 Old Bailey, London, EC4M 7AU, United Kingdom |
Paddle Payments Ltd (Dublin) contracts only where the supplier is registered for VAT in the United Kingdom, so it never applies to us: Hesed is Brazilian. We are on Paddle's standard Master Services Agreement, not a negotiated one.
So a US buyer's payment data is held in the United States, not in the UK or the EU. That is a transfer in its own right and is covered by the basis in Privacy Policy §4.
Emet subscriptions are sold through Paddle, which acts as the Merchant of Record — Paddle is the seller for the transaction, takes the payment, issues the invoice, and calculates and remits sales tax and VAT.
What they receive: the buyer's name and email address, billing address, any tax or VAT identifier, the country and IP used to determine the applicable tax, and the payment instrument itself. Also the plan purchased and the workspace identifier we pass so a payment can be matched to an account.
What they do not receive: any Customer Content. No source document, no translation, no translation-memory entry, no glossary term and no segment text of any kind reaches Paddle. Nor do they receive your other users — only the person who buys.
Card details never reach us. The checkout is hosted by Paddle. We do not see, transmit or store a card number, and no financial instrument exists anywhere in the platform's database. This row is therefore unusual in this list: it is the one subprocessor that holds a category of personal data the platform itself deliberately never touches.
Their role: Paddle acts as an independent controller for the payment, tax and anti-fraud processing it performs as seller of record, rather than purely as our processor. Paddle's own published terms say the same: their Data Sharing Addendum frames the relationship as one controller disclosing to another, and applies Module One (Controller–Controller) of the EU standard contractual clauses. Read 2026-09-09.
What Paddle sends back to us. The flow is not one-way. Because the buyer contracts with Paddle rather than with us, Paddle passes us what we need to provision and support the subscription: the buyer's name, email address and billing address, and their purchase history. We hold that as our own controller, for that purpose only. No card number is ever among it.
Changes to this list
We will give 30 days' written notice before adding a subprocessor that would receive Customer Content, during which you may object. A replacement made urgently for security or continuity reasons may be notified after the fact, promptly.
The practical trigger on our side is a new credential in the platform's configuration: if a new third-party API key is added, this page changes in the same change. Removing one — for example emptying GEMINI_TARGET_LANGS, which would remove §3 — is not something we would do without telling you either, since it changes translation output.
Widening one counts too. A credential is not the only trigger: changing GEMINI_TARGET_LANGS so that a subprocessor already on this list begins receiving content it did not receive before is a change to the scope of processing, and it gets the same notice. See the boxed note in §3.
What isolates one client from another
Not a subprocessor question, but the one your reviewer will ask next.
Every client is a separate tenant. Projects, files, segments, translation memory, glossaries, style profiles and pay data are all tenant-scoped, and the scoping is applied by the database layer rather than by each individual query — so a request made in one organisation's context cannot read another's rows. Translation memory in particular is shared across projects within your organisation, and never across organisations: content you translate never becomes a suggestion for another client, and no client's memory is used to draft your work.
This is enforced by api/app/tenancy.py, and there is a test that fails if a new tenant-owned table is ever added without being registered for filtering — because a hand-maintained list is exactly the kind of thing that goes wrong quietly.