# Quickstart

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

Source: https://www.fluentc.ai/docs/quickstart/

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](https://dashboard.fluentc.io/users/sign_up). 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](https://www.fluentc.ai/docs/authentication.md).

## 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](https://www.fluentc.ai/docs/api/languages.md).

## 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](https://www.fluentc.ai/docs/concepts.md#plans-and-modes).

## 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](https://www.fluentc.ai/docs/api/batch-results.md).

## 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.

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

The full list is on the [Errors](https://www.fluentc.ai/docs/api/errors.md) page.

## Next steps

- Read the [Translate](https://www.fluentc.ai/docs/api/translate.md) reference for every field and format.
- Learn how [translation memory and modes](https://www.fluentc.ai/docs/concepts.md) affect cost and speed.
- Connect FluentC to the tools you already use: [MCP](https://www.fluentc.ai/docs/integrations/mcp.md), [LangChain](https://www.fluentc.ai/docs/integrations/langchain.md), [n8n](https://www.fluentc.ai/docs/integrations/n8n.md), [Make and Zapier](https://www.fluentc.ai/docs/integrations/make-zapier.md) or [function calling](https://www.fluentc.ai/docs/integrations/function-calling.md).
