Why this is a data problem, not just a legal one
If you've ever worked on a legaltech product, cap table platform, or internal tooling for an M&A team, you've probably run into this: a shareholders' agreement needs to exist in two or more languages, and those versions have to be legally equivalent, not just linguistically similar.
The source article on shareholders' agreement translation for foreign investors covers the legal side well: why terms like "drag-along", "tag-along" or "liquidation preference" don't map cleanly across legal systems, and when you need certified translation versus an apostille versus consular legalisation.
What that article doesn't get into, and what's actually relevant if you're building tools around this process, is how you structure a pipeline that handles multilingual legal documents without losing track of which clause maps to which jurisdiction, which version is authoritative, and which terminology decisions were made and why.
This is squarely a document management and terminology consistency problem. Let's break down how to approach it technically.
The core challenge: terminology isn't 1:1
Standard translation APIs (Google Cloud Translation, DeepL API, Azure Translator) are built on the assumption that a term in language A has a reasonably stable equivalent in language B. Legal terminology breaks that assumption constantly.
"Shareholders' agreement" and "acordo parassocial" don't cover identical scope in every jurisdiction. "Vesting" or "cliff period" may not have a single fixed Portuguese equivalent at all. If you naively run a 40-page contract through a generic MT engine, you'll get fluent Portuguese that is quietly wrong in ways a non-lawyer reviewer won't catch.
If you're building or integrating translation tooling for legal documents, don't treat this as a translation problem. Treat it as a controlled vocabulary problem.
Practical approach: terminology databases over raw MT
Most serious CAT tools (SDL Trados, memoQ, Smartcat) support termbases — structured glossaries that get enforced during translation, whether human or machine-assisted. If you're building something custom:
# Simplified example: enforcing a legal termbase before/after MT pass
import json
with open("legal_termbase_en_pt.json") as f:
termbase = json.load(f)
# termbase = {"drag-along right": "direito de arrastamento", ...}
def flag_unmapped_terms(source_text, termbase):
flagged = []
for term in termbase:
if term.lower() in source_text.lower():
flagged.append(term)
return flagged
def enforce_termbase(mt_output, source_text, termbase):
issues = []
for term, approved_translation in termbase.items():
if term.lower() in source_text.lower():
if approved_translation not in mt_output:
issues.append((term, approved_translation))
return issues
This won't replace a qualified legal translator, but it gives you an automated first-pass QA layer: anywhere the source contains a term from your controlled vocabulary and the output doesn't contain the approved equivalent, you flag it for human review instead of letting it slip through silently.
The real engineering work is building and maintaining that termbase per jurisdiction pair (PT-EN for UK/US investors, PT-DE, PT-FR, PT-AO for Angola, etc.), since, as the source article points out, even Portuguese-speaking jurisdictions diverge on substantive points like share transfer rules.
Versioning: treat contract translations like code
A shareholders' agreement under negotiation goes through redlines. Each redline on the source language needs to propagate to every translated version, and you need an audit trail of which translated clause corresponds to which source revision.
This maps surprisingly well to standard version control concepts:
- Store each language version as a separate file in the same repo, aligned by clause ID, not by line number (contract clauses get renumbered constantly).
- Use a structured format (XML, or even a constrained Markdown with clause anchors) instead of raw
.docx, so diffs are meaningful. - Tag releases at the point a version is sent for certified translation or apostille, so you can always answer "which exact text was certified".
<clause id="cl-14-drag-along" status="certified" lang="pt" source-rev="v12">
<text>O acionista maioritário pode exercer o direito de arrastamento...</text>
</clause>
If your org handles more than a handful of these a year, this structure is worth building even as a thin layer on top of Git, with clause-level metadata tracked separately from prose.
Automating the certification/apostille decision tree
The source article lays out a genuinely useful decision tree:
- Document stays in Portugal → certified translation via a lawyer or notary (no "sworn translator" concept in Portugal)
- Document used in a Hague Convention country → apostille via PGR
- Document used in a non-Convention country (e.g. Angola) → consular legalisation via Ministério dos Negócios Estrangeiros + destination embassy
- Document used in Brazil, Spain, France, Germany → destination country's own sworn/certified translator regime applies
This is a clean candidate for a small rules engine rather than a wiki page someone has to remember to check:
HAGUE_COUNTRIES = {"US", "UK", "DE", "FR", "ES", ...} # populate from official list
NON_HAGUE = {"AO"} # Angola, etc.
def required_authentication(destination_country, origin="PT"):
if destination_country == origin:
return "certified_translation_only"
if destination_country in HAGUE_COUNTRIES:
return "certified_translation_plus_apostille"
if destination_country in NON_HAGUE:
return "consular_legalisation"
if destination_country in {"BR", "ES", "FR", "DE"}:
return "destination_sworn_translator_regime"
return "manual_review_required"
This is trivial code, but encoding it means your legal ops team (or your SaaS product, if you're building for legal/compliance) stops relying on institutional memory for a decision that has real consequences if gotten wrong. Keep the underlying lists in a config file that gets reviewed quarterly, these rules do change.
Where human review still has to sit in the loop
None of the above replaces qualified legal translators. The source article mentions a workflow with three linguists (translator, editor, QC reviewer) under ISO 17100, which is the right instinct: high-stakes legal documents need redundant human review, not just better tooling.
What the tooling buys you is:
- Catching terminology drift before it reaches a human reviewer, so their time goes to judgment calls, not typo-hunting
- A reliable audit trail of which version was certified, apostilled, or legalised, and when
- A repeatable, testable decision process for the certification/apostille/legalisation question, instead of re-deriving it on every deal
If you're building internal tooling for a legal, compliance, or corporate development team that handles cross-border contracts regularly, this is a reasonable architecture to start from. If you're handling a one-off shareholders' agreement for an actual deal, skip the tooling and go straight to a legal translation provider with a documented ISO 17100 process, the stakes are too high for a DIY pipeline on a single contract.












