TextUnited
What we doPricing
Language operations API

Run translation inside the systems you already have.

Send content from your CMS, PIM or repository as segments. TextUnited translates it against your terminology and style rules, then returns the results through the API.

TextUnited · API
POST/segments/projects

customId: "catalogue-2026.08"

taskId: "release-notes"

targetLanguages: ["de-AT", "pl-PL"]

segments: 12,400

Translation in progress6 languages

The shape of the integration

The API works with the content you already have.

Segments, not filesSend strings from a CMS, PIM, repository or database. A segment can contain HTML.
Your identifiers throughoutSet your own customId on the project and on each segment. Your integration never has to map your IDs to ours.
Your language rules, already thereEach target language carries its own services, its own team and its own progress, inside the one project you created.

Context stays with the segment

A note attaches to a segment. 'languageSpecificNotes' sets a different note for each target language, so the German translator reads one instruction and the Polish translator reads another. The character limit, the screenshot reference, the note that this string appears on a button reach the person doing the work rather than staying in the ticket that started the job.

json
json
Authorization: Basic <companyId:apiKey>

{
  "customId": "catalogue-2026.08",
  "name": "Product catalogue — August release",
  "taskId": "release-notes",
  "sourceLanguageCode": "en-US",
  "domainId": 7,
  "endDateUtc": "2026-08-28T17:00:00Z",
  "eventUrl": "https://your-system/hooks/textunited",
  "targetLanguages": [
    { "targetLanguageCode": "de-AT",
      "serviceTranslation": true, "serviceProofreading": true,
      "styleGuideId": 412 },
    { "targetLanguageCode": "pl-PL",
      "serviceAutomaticTranslation": true, "serviceScoring": true }
  ],
  "segments": [
    { "customId": "sku-4471.name",
      "content": "Telescopic mast, 12 m",
      "notes": "Product title — 40 character limit" },
    { "customId": "sku-4471.desc",
      "content": "<p>Rated to <b>12 m</b> working height.</p>" }
  ]
}

That single call is the integration. Everything after it is your own customId and a webhook.

What teams wire this to:

  • A repository calls the API from CI, so strings are translated on merge and localized builds ship with the release.
  • A headless CMS calls it on publish, so one editorial action reaches every market.
  • A documentation build in Markdown runs in every language with each release.
  • A PIM sends the product catalogue each cycle instead of re-exporting all of it.

The smallest possible first step

You can call it before you commit to any of this.

POST /segments/Translation takes segments and target languages and returns the translations in the same response. It creates no project and schedules nothing. Each translation comes back with your own customId on it, so you map the results to your own content without storing anything of ours.

Point it at a hundred of your own strings and compare the output to what you use now.

You do not have to choose between the two. Set instantTranslation on a real project and a first pass comes back immediately while the human work continues.

What the segments run against

Any model can translate. None of them can know what your company already decided.

A model does not know which of three defensible terms your company uses, that legal rejected one of them for one market, or that a reviewer has already corrected this string twice.

Three things decide the output before the model sees it.

Approved terminologyThe term your company settled on, and the ones it rejected.
Translation memoryEvery sentence your reviewers have already confirmed.
Style guidesRegister and rules, held as configuration rather than as a PDF.

TextUnited applies all three while the translation is produced, not to the output afterwards, so they hold when you change model.

Each one is scoped, not global.

Terminology is grouped into domains you define, because the vocabulary of your service manuals is wrong on your marketing site. A narrower guide states only the rules that change at that level. The rules from the wider guides still apply.

The request carries pointers, not payload.

The terms and rules stay on your account. Omit the domain and nothing lapses: your account-wide terminology still applies, because the domain narrows which set governs a project rather than switching governance on.

Set per language, not per integration

Not every language deserves the same money.

Most integrations force one answer for the whole payload. Everything goes to a machine, or everything goes to people. You set the services on each target language instead, inside the same project and in the same request.

de-AT

Human, then proofread

The market that reads your manuals closely: translation and proofreading against the style guide legal approved.

pl-PL

Automatic, and scored

Volume that has to exist in the language but does not need a person on every string.

fr-FR

Adaptive, managed by us

Where the volume is real and the team is not: adaptive translation against your record, run as a managed project.

You can also change your mind per release. The methodology lives on the target language of a project, not in your integration code — so moving a market from machine to human is a field in the next request, not a sprint.

Set a score threshold and it decides who reads the segment.

Set serviceScoring on a target language and every machine-translated segment gets a quality estimate. You configure the threshold rather than passing it: the call asks for a score, and your settings decide what counts as high enough. Above the threshold the segment passes. Below it, a reviser reads the segment before a customer does.

You then stop choosing between reviewing everything and reviewing nothing, and you set the threshold at whatever level you made the decision.

Per accountYour default for everything.
Per domainHigher where the content carries liability, lower on the internal knowledge base.
Per language pairHigher again where your machine translation is weakest.

Your own translators can do the work.

team assigns users to a language project as project manager, translator, proofreader or in-country reviewer, and one person can hold several of those roles. A project created by an API call arrives with its team assigned, so nobody opens the interface to hand out work the calling system already knew about. Each member carries a translation rate and a proofreading rate in the project currency, so an API-created project costs what the same project costs when a person creates it.

How you know where it is

Segments come back one at a time, and a better version can replace each one.

Creating a project returns an acknowledgment. Machine translation lands almost immediately; human work arrives segment by segment, under the IDs you sent. Every translation carries a status, and your integration decides which status it publishes from. Take automatic today for an internal preview and proofread for the storefront when it arrives, from the same project and the same call.

eventUrl tells you when something changed. GET /segments/projects/{id}/progress gives one percentage plus a breakdown per task and language.

json
json
[
  {
    "source": { "customId": "sku-4471.name",
                "content": "Telescopic mast, 12 m" },
    "translations": [
      { "languageCode": "de-AT",
        "content": "Teleskopmast, 12 m",
        "status": "proofread",
        "comments": [ ... ] }
    ]
  }
]

The status filter is the useful part. Ask only for what is proofread and you can publish continuously without waiting for the slowest language in the release.

Every segment sits at one of six statuses, and they are not synonyms.

StatusMeaning
untranslatedNo translation exists yet.
draftSomeone has started. Not a state to publish from.
automaticMachine output. No person has looked at it.
pretranslatedFilled from your translation memory.
translatedA person produced it.
proofreadA second person checked it. Safe to publish.

Machine output and proofread output are both "finished." Only one of them is safe to publish.

When it comes back wrong

A project created by API is the same object as one created by hand.

Your own translators and reviewers can be assigned to it, but we also have our own team to help you. They see it where they see everything else, and their corrections stay in your language data. Your system posts a comment onto one segment, by your own segment ID, in one target language or in all of them, so a bug report from a market lands on the string it concerns. When that segment comes back, its comments come with it.

Security and legal

What security and legal will ask before anyone writes code.

SOC 2 compliant, GDPR ready

AES-256 encryption at rest and in transit.

Hosted on Microsoft Azure

Your data stays in the region you select.

Isolated per tenant

Your language data is never used to train anything outside your account.

Granular RBAC and audit trails

Who did what, to which segment, when.

Scope is not a parameterWhich company you are is read from the credential, never from the request. Every project and segment lookup is filtered by it server-side. There is no field an integration can get wrong, or a curious engineer can change, that returns another tenant's content.
Failures come with a handleA rejected request returns the business reason in plain text. An unexpected one returns an error signature — a GUID recorded against the server-side log. Quote it to support and the exact request is found, without you reproducing anything or sending us your content.

The whole surface

Twelve endpoints. You will use four.

This is not a platform you have to learn. Create, update, read back, check progress — the rest exists for the cases you have not hit yet. Paths shown against the segments service; every one that takes an {id} has a custom/{customId} twin.

MethodEndpointPurpose
POST/segments/projectsCreate a project from segments and target languages. Returns on acceptance; preparation continues in the background.
PUT/segments/projectsUpdate in place — identified by the id or customId in the body, not the path. appendContent adds to a task rather than replacing it.
GET/segments/projectsEvery segment project in your company.
GET/segments/projects/{id}One project and its settings. Or /projects/custom/{customId}.
GET/segments/projects/{id}/segmentsSource segments with their translations. Filter by ?status= and ?taskId= to take only what is finished.
GET/segments/projects/{id}/progressOverall percentage, plus a breakdown per task and per target language.
POST/segments/projects/{id}/segments/commentsComment on a segment — one target language, or all of them. Addressable by your segment customId.
POST/segments/TranslationInstant translation with no project created and nothing persisted. Segments in translations back in the same response.
DELETE/segments/projects/{id}Remove a project. Also by customId.

Interactive schema is served from the service itself, so the contract you test against is the one that is deployed rather than a document that drifted from it. Every request accepts Basic or bearer credentials on the same path.

Start with the reference

Read it, then a short call about what triggers what.

Most integrations are settled in one conversation: which event on your side creates a project, what happens when quality does not hold, and who needs to know. That is shorter than the code.

Not a new productThese are the endpoints TextUnited has run on internally for more than ten years — the same interface behind the web application our own customers have been working in that whole time. What changed is that we are opening them directly to clients. You are integrating against something load-bearing, not against a beta that was written to have an API story.
No separate API priceAPI access is part of the OnePlatform plan, and it consumes the word allowance in your subscription exactly as translating a document through the interface does. The same words cost the same whether a person uploads them or your CMS posts them. There is no per-call charge to model and no second contract to negotiate.

Before the technical call

FAQs

Do we have to send files?

No. The API takes segments as objects with target languages attached to the project. Content held in a database, a PIM or a repository goes in as it is held.

Do we have to store your IDs?

No. Set your own `customId` on the project and on each segment, then use them for every subsequent call.

What does the second run cost?

Less, because `taskId` determines what a request updates. Send what changed and the project updates in place.

What does API access cost?

Nothing on top of your plan. API access is included in OnePlatform and consumes the same word allowance as translating through the interface.

How long has this been running?

More than ten years, internally. These are the endpoints the TextUnited web application itself is built on.

How do we authenticate?

Basic authentication with your company ID and API key, or a JWT bearer token, selected from the `Authorization` header.

Does the response contain the translations?

For `POST /segments/Translation`, yes — inline. For a project, translations arrive progressively afterwards.

How do we know when a language is finished?

Use the `eventUrl` webhook or `GET /segments/projects/{id}/progress` for progress per task and language.

Can different languages take different routes?

Yes. Machine, adaptive, human, proofreading, scoring and managed service are each set on the individual target language.

How are language variants handled?

`de-DE` and `de-AT` can run as separate targets, each with its own terminology, style guide and reviewer.

Can segments contain HTML?

Yes. Segment content is plain text or HTML, so markup from a CMS or documentation build survives the round trip.

Do we have to pass our glossary with every request?

No. The request names a `domainId` and a `styleGuideId`; the terms and rules stay on your account.

Can our own translators work on projects the API creates?

Yes. It is the same project object, and the same people can be assigned to it.

Close

The integration is small. What it connects to is not.

Posting content to a model and getting content back was never the hard part, and you already know that. Read the reference, and bring the case where it stops being simple.