Documentation menu

Quickstart

Make your first real-time translation and your first batch translation in a few minutes, with cURL, Python or Node.

View as Markdown

By the end of this page you will have listed your languages, translated a sentence in real time, and translated an HTML page in batch mode.

Before you start

You need an API key. Create one in the dashboard. Export it so the examples run as written:

bash
export FLUENTC_KEY="YOUR_FLUENTC_KEY"

Never put the key in client-side code. Call FluentC from a server, a workflow or an agent runtime. See Authentication.

1. Check which languages you can use

A target language must be enabled for your key. List them:

bash
curl https://api.fluentc.ai/ai_agent/languages \
  -H "Authorization: $FLUENTC_KEY"
json
{
  "supported_languages": [
    { "code": "es", "name": "Spanish" },
    { "code": "fr", "name": "French" },
    { "code": "de", "name": "German" }
  ],
  "source_languages": [
    { "code": "en", "name": "English" }
  ]
}

Use the code values as target_language and source_language. See Languages.

2. Translate in real time

cURL:

bash
curl https://api.fluentc.ai/ai_agent/translate \
  -H "Authorization: $FLUENTC_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "input": "Your order has shipped.",
    "input_format": "text",
    "target_language": "es",
    "mode": "real-time"
  }'

Python:

python
import os
import requests

res = requests.post(
    "https://api.fluentc.ai/ai_agent/translate",
    headers={"Authorization": os.environ["FLUENTC_KEY"]},
    json={
        "input": "Your order has shipped.",
        "input_format": "text",
        "target_language": "es",
        "mode": "real-time",
    },
)
res.raise_for_status()
print(res.json()["translation"])

Node:

js
const res = await fetch("https://api.fluentc.ai/ai_agent/translate", {
  method: "POST",
  headers: {
    Authorization: process.env.FLUENTC_KEY,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    input: "Your order has shipped.",
    input_format: "text",
    target_language: "es",
    mode: "real-time",
  }),
});
if (!res.ok) throw new Error(`${res.status} ${(await res.json()).error}`);
console.log((await res.json()).translation);

The response:

json
{
  "status": "complete",
  "translation": "Tu pedido ha sido enviado.",
  "token_count": 9,
  "source_language_detected": "en"
}

Note: Real-time mode needs the Real-time plan. With a Batch plan key the API answers 422 with "Realtime translation is not supported for this agent." Use batch mode instead, below. See Concepts.

3. Translate in batch

Batch mode accepts the request, returns a job_id straight away, and translates in the background. You poll for the result.

Submit the job:

bash
curl https://api.fluentc.ai/ai_agent/translate \
  -H "Authorization: $FLUENTC_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "input": "<h1>Welcome</h1><p>This is a sample page.</p>",
    "input_format": "html",
    "target_language": "fr",
    "mode": "batch"
  }'
json
{ "job_id": "abc123def456" }

Poll until status is complete:

bash
curl https://api.fluentc.ai/ai_agent/results \
  -H "Authorization: $FLUENTC_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "job_id": "abc123def456" }'
json
{
  "status": "processing",
  "estimated_wait_seconds": 5,
  "next_poll_after": "2026-01-15T10:30:00Z"
}

Here is the whole flow in Python, with a cap on the number of polls:

python
import os
import time
import requests

BASE = "https://api.fluentc.ai"
HEADERS = {"Authorization": os.environ["FLUENTC_KEY"]}

job_id = requests.post(
    f"{BASE}/ai_agent/translate",
    headers=HEADERS,
    json={
        "input": "<h1>Welcome</h1><p>This is a sample page.</p>",
        "input_format": "html",
        "target_language": "fr",
        "mode": "batch",
    },
).json()["job_id"]

for _ in range(60):
    result = requests.post(
        f"{BASE}/ai_agent/results", headers=HEADERS, json={"job_id": job_id}
    ).json()
    if result["status"] == "complete":
        print(result["translation"])
        break
    if result["status"] == "failed":
        raise RuntimeError(result["error"])
    time.sleep(max(result.get("estimated_wait_seconds", 5), 5))
else:
    raise TimeoutError(f"Job {job_id} did not finish")

Always cap the number of polls. A job_id that doesn't exist is reported as processing, not as an error. See Batch results.

4. Handle errors

Every error is JSON with an error string and an HTTP status you can branch on. Check the status before reading the body.

StatusMeaning
401The key is missing or wrong. Check for a stray Bearer prefix.
403The subscription is inactive, translation is disabled, or a usage limit was reached.
422The request is invalid. The message names the problem.

The full list is on the Errors page.

Next steps

Something unclear, or missing? Tell us.