Most engineering teams building multilingual products hit the same wall: translation logic scattered across microservices, inconsistent terminology, no centralized quality enforcement, and no visibility into what got translated, when, or how well. Every new locale adds another brittle integration. The fix is not another point-to-point connector, it is a dedicated translation API layer that acts as an orchestration gateway between your content systems and the AI engines, human reviewers, and quality checks that produce production-grade translations. This guide walks through the architecture of that gateway: from OpenAPI contract design and intelligent job routing, through async processing and caching, to security hardening, observability, and pluggable QA hooks. By the end, your team will have a concrete blueprint for a scalable, auditable translation gateway. Platforms like Ollang implement this gateway pattern as a managed service, reducing the engineering effort required to stand up a production-grade orchestration layer.
API Contract Design: OpenAPI, Versioning, and Idempotency
A translation API layer is only as good as its contract. Start with an OpenAPI 3.1 specification as the single source of truth. This gives consumers auto-generated SDKs, self-documenting endpoints, and schema validation at the gateway level before any translation work begins.
Defining Resource Models and Endpoints
Structure your API around two core resources: Translation Jobs and Translation Results.
| Endpoint | Method | Purpose |
|---|---|---|
| /v1/jobs | POST | Submit a new translation job |
| /v1/jobs/{jobId} | GET | Poll job status and retrieve results |
| /v1/jobs/{jobId}/cancel | POST | Cancel an in-progress job |
| /v1/results/{jobId} | GET | Fetch completed translation segments |
| /v1/glossaries | CRUD | Manage terminology assets |
Use plural nouns, version the base path (/v1/), and avoid verbs in resource URIs. Represent job lifecycle states explicitly: queued, processing, review, completed, failed, cancelled.
Idempotency Keys and Safe Retries
Network failures are inevitable. Every POST /v1/jobs request should require an Idempotency-Key header, a client-generated UUID. The gateway stores this key alongside the job record. If a duplicate key arrives, the gateway returns the original response without re-processing. This prevents double-billing and duplicate translations. Set a TTL on idempotency records (typically 24-48 hours) and return 409 Conflict if a key is reused after the original job has been cancelled or expired.
Versioning Strategy
Use URL-path versioning (/v1/, /v2/) rather than header-based versioning for discoverability. Maintain backward compatibility within a major version by treating new fields as optional. Deprecate endpoints with a Sunset header and a minimum 90-day notice window, giving consuming teams time to migrate.
Content Segmentation and Context Packaging
Raw content rarely arrives in a format suitable for direct MT engine consumption. The gateway must segment, enrich, and package content before routing.
Segmentation Rules by Content Type
Different content types demand different segmentation strategies:
- UI strings (JSON, XLIFF, ARB): Already segmented by key. Preserve key-value structure and pass metadata like character limits, platform context, and ICU MessageFormat placeholders.
- Documents (HTML, Markdown, DOCX): Parse into translatable segments using sentence-boundary detection. Protect inline markup (tags, variables, placeholders) by wrapping them in non-translatable tokens.
- Legal and regulatory text: Segment at paragraph or clause level to preserve contractual meaning. Flag sections requiring certified human review.
- Subtitles and captions (SRT, VTT): Segment by timecoded block. Pass timing constraints so the engine can respect character-per-second limits.
Use the Unicode Segmentation standard (UAX #29) as a baseline for sentence breaking, then layer domain-specific rules on top.
Context Windows and Metadata Injection
Translation quality improves when engines receive context beyond the isolated segment. Package each segment with:
- Preceding and following segments (a context window of 2-3 sentences).
- Source metadata: content type, domain tag (legal, marketing, UI), product area, target audience.
- Glossary terms that appear in the segment, pre-resolved to their approved translations.
- Translation memory (TM) matches above a configurable threshold (e.g., 75% fuzzy match), so the engine can leverage prior approved translations.
Represent this as a structured context object in the request payload rather than concatenating everything into a single string. This keeps the contract explicit and lets different engines consume context differently.
Terminology Injection and Glossary Management
Inconsistent terminology is one of the fastest ways to erode brand trust across locales. The gateway should enforce terminology at the API level, not leave it to individual engine configurations.
Glossary Lifecycle
Expose a /v1/glossaries CRUD endpoint. Each glossary entry maps a source term to one or more locale-specific translations, along with metadata: part of speech, usage notes, do-not-translate flags, and domain scope. Version glossaries immutably, every update creates a new version, and jobs reference a specific glossary version for reproducibility.
Injection Strategies
There are two complementary injection points:
- Pre-translation injection: Before sending segments to the engine, scan for glossary matches and annotate them inline (e.g., using XML tags or a structured hint field that the engine's API supports). Most modern MT APIs, including those from Google, DeepL, and OpenAI, accept glossary hints in some form.
- Post-translation validation: After the engine returns results, scan the target text to verify that glossary terms were applied correctly. Flag violations as QA warnings and optionally block delivery until resolved.
This dual approach catches both engine-side glossary failures and edge cases where morphological variation causes a miss.
Job Routing: Domain, Quality Tier, and Engine Selection
Not every translation job should go to the same engine. A marketing tagline needs a different quality profile than a system log message. The gateway's router is where this logic lives.
Routing Dimensions
Define routing rules across three dimensions:
| Dimension | Example Values | Effect |
|---|---|---|
| Domain | legal, marketing, ui, support | Selects engine fine-tuned for that domain |
| Quality tier | draft, production, certified | Determines whether MT-only, MT + LQA, or MT + human review |
| Language pair | en→de, en→ja, en→ar | Some engines perform better for specific pairs |
Store routing rules in a configuration layer (not hardcoded) so they can be updated without redeployment. A simple decision table works well initially; more sophisticated setups use a rules engine or weighted scoring.
Multi-Engine Fallback
Configure primary and fallback engines per route. If the primary engine returns an error or exceeds latency SLOs, the gateway automatically retries with the fallback. Log every fallback event for later analysis, a spike in fallbacks signals an engine reliability issue.
For organizations that need to orchestrate across multiple AI engines, glossary systems, and human review workflows without building this routing logic from scratch, Ollang offers a managed orchestration layer that handles engine selection, terminology enforcement, and quality routing out of the box. It integrates with major engines and review platforms and surfaces logs and metrics for auditing. Book a demo to see it in action: https://ollang.com/book-a-demo
Async Processing: Queues, Webhooks, and Retry Logic
Translation jobs, especially those involving large documents, multiple target locales, or human review steps, are inherently asynchronous. Design for this from the start.
Queue Architecture
Use a durable message queue (RabbitMQ, Amazon SQS, or Google Cloud Pub/Sub) between the API gateway and the processing workers. When a job is submitted:
- The gateway validates the request, creates a job record with status queued, and returns 202 Accepted with the jobId.
- A message is published to the appropriate queue (routed by domain/tier).
- Workers consume messages, call the selected engine, run post-processing, and update the job record.
This decouples ingestion throughput from processing throughput and lets you scale workers independently per queue.
Webhook Delivery
Consumers register webhook URLs via the API or during job submission. When a job transitions to a terminal state (completed, failed), the gateway sends a signed webhook payload:
{
"event": "job.completed",
"jobId": "abc-123",
"timestamp": "2025-01-15T10:32:00Z",
"locale": "de-DE",
"qualityScore": 0.94
}
Sign payloads with HMAC-SHA256 using a shared secret so consumers can verify authenticity. Include an X-Signature header with the value sha256=<hex-digest> and document the verification algorithm in your API spec.
Retries and Exponential Backoff
Engine calls fail. Network partitions happen. Implement retries with exponential backoff and jitter:
- Initial delay: 1 second
- Multiplier: 2x
- Max retries: 5
- Jitter: ±25% randomization to prevent thundering herds
For webhook delivery, retry failed deliveries (non-2xx responses) on a similar schedule, up to 72 hours. Store delivery attempts in an audit log and expose a /v1/webhooks/{id}/deliveries endpoint so consumers can debug failures.
MT Caching: Cache Keys, ETags, and Diff-Based Invalidation
Redundant translation calls waste money and add latency. A well-designed caching layer can reduce engine calls significantly, especially for content that changes incrementally.
Cache Key Construction
Build cache keys from the combination of factors that determine a unique translation:
cache_key = hash(source_text + source_locale + target_locale + engine_id + glossary_version + model_version)
Include the glossary version and model version in the key. A glossary update should invalidate affected cache entries, not serve stale translations with outdated terminology.
ETag-Based Conditional Requests
Return an ETag header with every translation result. When a consumer re-requests a translation for the same source content, they pass the ETag via If-None-Match. If the cached translation is still valid, return 304 Not Modified with zero body, saving bandwidth and processing time.
Diff-Based Invalidation
For documents that change incrementally (e.g., a product description where one sentence was edited), don't retranslate the entire document. Diff the new source against the cached source at the segment level. Only segments with actual text changes get sent to the engine; unchanged segments are served from cache. This approach can reduce engine calls by a substantial margin on iterative content workflows, where most updates touch only a fraction of total segments.
Store cached translations with TTLs appropriate to the content type: UI strings might cache for 30 days, while news content caches for hours.
