fluentc/platform
Live5,541translations / sec

Translation infrastructure for the agent era.

Most translation APIs were designed when "translation" meant a human pasted text into a web form. FluentC was designed for what translation is now: an agent calling an API thousands of times an hour, in the middle of a workflow, expecting an answer back before the user notices.

That shift changes everything underneath the API — how caching works, how batches are handled, how pricing is structured, how rate limits behave. We rebuilt the stack around it.

What's in the platform

One product. A few moving parts. Here's the tour.

Each section links to a deeper page if you want the full story.

01Translation API

One endpoint, three input formats, one UUID for auth.

POST /ai_agent/translate handles text, HTML, and JSON. You pick the input format, the target language, and whether you want the answer back synchronously or as a batch job. That's the whole surface area.

Authentication is a single UUID in the Authorization header. No token exchange, no client libraries required to get going. curl works. n8n works. A LangChain tool works. Whatever you're holding works.

Read the API reference
POST /ai_agent/translate
curl -X POST https://api.fluentc.io/ai_agent/translate \
  -H "Authorization: 4f3a-uuid-...-9c2e" \
  -H "Content-Type: application/json" \
  -d '{
    "input_format": "json",
    "target_language": "es",
    "mode": "sync",
    "content": { "title": "Hello", "body": "Welcome" }
  }'

# 204ms · 200 OK
{
  "translation": {
    "title": "Hola",
    "body": "Bienvenido"
  },
  "target_language": "es",
  "tm_hit": false,
  "request_id": "tx_8f3a72c4"
}
input_format: text
plain string
input_format: html
preserves tags + attrs
input_format: json
walks the structure
02Real-time translation

For when an agent is mid-conversation and needs the answer now.

Synchronous request, translated text in the response, no polling.

Behind the scenes there's a content-addressed cache keyed on SHA256(target_language + input). The second time the same string comes through, you skip the model entirely — same translation, same key, faster response.

This matters more than it sounds like it should. A multilingual chatbot answering "hello" in twelve languages will hit that cache constantly.

See how real-time mode works
Live cache observer
"hello" → translate(target_language=*)
STREAMING
PL
cześć
CACHE HIT
8ms
VI
xin chào
CACHE HIT
10ms
TH
สวัสดี
CACHE HIT
10ms
EN
hello
CACHE HIT
10ms
ES
hola
CACHE HIT
7ms
FR
bonjour
CACHE HIT
11ms
JA
こんにちは
CACHE HIT
10ms
DE
hallo
CACHE HIT
8ms
cache_hits = 8 · model_calls = 0 · session = 39saved $0.0064
Job · batch / json
job_id = sha256(input)[:12]
● COMPLETED
INPUT · EN
{
"title": "Hello",
"body": "Welcome",
"cta": {
"label": "Start"
}
}
FAN OUT · 3 STRINGS
OUTPUT · ES
{
"title": "Hola",
"body": "Bienvenido",
"cta": {
"label": "Empezar"
}
}
ROWS
50,000
PARALLEL
32 workers
DURATION
47s
03Batch translation

For when you've got 50,000 rows and you need them all in one go.

Submit the job, get a job_id back, poll for results when you're ready. Works for a Google Sheet, a product catalog, a directory of JSON i18n files — anything.

JSON is handled properly: nested structures are walked, every string value gets translated independently and in parallel, and the original shape is reassembled at the end. Keys stay keys. Structure stays structure.

The same job_id is safe to poll forever — it's a deterministic hash of your input, not a random ticket. Re-submit the same content and you get the same job_id back and the same cached result.

See how batch mode works
04Translation memory

Pay once for "Add to cart." Forever.

Translation memory is a database of translations you've already paid for. The next time the same string comes through, you don't pay again — and the response is faster because it doesn't hit the model.

Most translation APIs charge you per character every time. We don't. For ecommerce catalogs, support macros, and any product with repeating strings, this is where most of the savings come from.

You can also overwrite specific translations on a per-site basis when you want a different rendering than the model's default. The cache respects your overrides.

Read about translation memory
TM LEDGER · "Add to cart"
tm:8c4a91…2e7b
● cached
2026-03-04ES· model call$0.0008
2026-03-04FR· model call$0.0008
2026-03-04JA· model call$0.0008
2026-03-11ES✓ tm hit$0.0000
2026-03-18ES✓ tm hit$0.0000
2026-04-02FR✓ tm hit$0.0000
2026-04-12JA✓ tm hit$0.0000
2026-05-01ES✓ tm hit · custom override$0.0000
BILLED · 8 CALLS$0.0024
saved $0.0040 against per-character billing
05Supported languages

The catalog you'd expect, scoped to whichever agent is asking.

The major European languages, the major Asian languages, Arabic, Hebrew, Hindi, and the long tail beyond that.

The list is cached and exposed at GET /ai_agent/languages, scoped to whatever you've enabled on your agent.

Add or remove languages from your dashboard. Each agent has its own enabled set — so a Shopify agent translating into ten languages and an internal support agent translating into three can live under the same account.

See the full language list
GET /ai_agent/languages
200 · 128 enabled
enEnglish
esSpanish
frFrench
deGerman
itItalian
ptPortuguese
nlDutch
svSwedish
noNorwegian
daDanish
plPolish
csCzech
trTurkish
elGreek
ruRussian
ukUkrainian
arArabic
heHebrew
hiHindi
bnBengali
jaJapanese
koKorean
zhChinese
viVietnamese
thThai
idIndonesian
msMalay
tlTagalog
swSwahili
faPersian
urUrdu
taTamil
+96more
How it actually performs

Five things worth knowing if you're evaluating.

01
Hash-keyed cache.

Identical input + target language is a cache hit. No "fuzzy match" surprises, no per-call billing on repeat strings.

sha256(target + input) → cache key
02
Deterministic job IDs.

Re-submitting the same batch input returns the same job_id. Idempotent by design.

job_id = hash(input)
03
Retry behavior baked in.

Background translation jobs retry on model timeouts (5 attempts, exponential backoff) and rate limits (10 attempts, respecting Retry-After). You don't have to build this yourself.

timeout: 5x exp · 429: 10x · Retry-After honored
04
JSON batches run in parallel.

A document with 200 string values doesn't run 200 sequential model calls — it fans out and reassembles.

fan-out · 32 workers · reassemble
05
One header, no SDK required.

The whole API is reachable from curl. SDKs exist if you want them; they're not a prerequisite.

Authorization: <uuid>
Want the raw shape of the API?

The OpenAPI spec is published at /ai_agent/swagger.yml and the interactive docs at /ai_agent/docs.