# Bulk AI Translator: Website, Files & Datasets (No API Key) (`fayoussef/bulk-ai-translator`) Actor

Translate product catalogs, websites, datasets, CSV/XLSX/JSON files and SRT/VTT subtitles into 40+ languages. AI translation with brand-term locking and HTML/placeholder safety. No API key, and repeat runs only pay for what changed.

- **URL**: https://apify.com/fayoussef/bulk-ai-translator.md
- **Developed by:** [youssef farhan](https://apify.com/fayoussef) (community)
- **Categories:** AI, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 translated items

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

Translate websites, product catalogs, spreadsheets and subtitles into 40+ languages in bulk, with no API key and no subscription.

### What does Bulk AI Translator do?

**Bulk AI Translator** translates text at scale from four different sources: a **list of strings**, an **Apify dataset** produced by any other Actor, a **crawled website**, or **files** you host anywhere (PDF, CSV, TSV, XLSX, JSON, SRT, VTT, Markdown, TXT). It returns clean structured rows plus rebuilt, ready-to-download files in the same format you supplied.

You do **not** need an OpenAI, DeepL, Google Cloud or Lingo API key. You do not need a monthly localization subscription. Billing runs through your Apify account on a pay-per-use basis, and you can call the Actor from the API, run it on a schedule, chain it into integrations, or invoke it from an AI agent through the Apify MCP server.

Two things make it safe for real production data. **Brand terms and placeholders survive intact**: HTML tags, `{{variables}}`, `%s` format strings, URLs, emails and any glossary terms you list are masked before translation and restored afterwards, and any segment that comes back corrupted is retried and then falls back to the source rather than shipping broken output. And **repeat runs are cheap**: every translated string is cached, so a scheduled re-run of a mostly unchanged catalog only pays for what actually changed.

### Why use Bulk AI Translator?

- **Translate a product catalog** for a new market without paying per-language subscription tiers.
- **Localize a website** by crawling it and getting every page's title, meta description and body text back in your target languages, ready for your CMS.
- **Translate any scraper's output.** Run a Store Actor, copy its dataset ID, and get the same rows back in another language. This is the fastest path from foreign-language web data to a dataset your team can actually read.
- **Translate SRT and VTT subtitles** with timestamps untouched and cues re-wrapped so lines stay readable after they get longer.
- **Localize spreadsheets and data feeds** by pointing it at a CSV or XLSX and getting the same file back, same columns, translated values.
- **Translate PDF documents** such as manuals, guides and reports. Text is extracted per page and returned as clean translated text.
- **Build multilingual RAG and AI training corpora** from scraped content.

### How to use Bulk AI Translator

1. Click **Try for free**.
2. Pick a **mode**: Text, Dataset, Website or File.
3. Fill in the one field that mode needs: your strings, a dataset picked from your account, start URLs, or file URLs. In File mode you can also upload a file straight from your computer.
4. Pick your **target languages** from the dropdown. Select as many as you need.
5. Optionally add **glossary terms** that must never be translated, and pick a **tone**.
6. Click **Start**, then download the results as JSON, CSV, Excel or HTML.

Everything else already has a sensible default. You can ignore the Limits and advanced section entirely on your first run.

### Input

Configure the run on the **Input** tab, or pass JSON through the API.

```json
{
  "mode": "dataset",
  "datasetId": "aBcD1234efGh5678",
  "fields": ["title", "description"],
  "targetLanguages": ["de", "fr", "es"],
  "tone": "marketing",
  "glossary": ["Acme", "AirFlow Pro"],
  "model": "google/gemini-2.5-flash"
}
````

Website mode instead:

```json
{
  "mode": "website",
  "startUrls": ["https://example.com"],
  "maxPages": 25,
  "targetLanguages": ["de"]
}
```

### Output

One row per item and target language. Dataset and file rows also carry the translated fields as extra columns, so a CSV export lands ready to use.

```json
{
  "unitId": "item-42",
  "kind": "record",
  "source": "aBcD1234efGh5678",
  "targetLanguage": "de",
  "targetLanguageName": "German",
  "sourceText": "Hand-poured soy candle with a warm vanilla scent.",
  "translatedText": "Handgegossene Sojakerze mit warmem Vanilleduft.",
  "title": "Handgegossene Sojakerze mit warmem Vanilleduft.",
  "description": "Brennt sauber fur bis zu 45 Stunden.",
  "fileUrl": null,
  "wordCount": 34,
  "segmentCount": 2,
  "cacheHits": 0,
  "error": null
}
```

Rebuilt files and translated pages are written to the key-value store, and each row links to its own file through `fileUrl`. Download everything as JSON, HTML, CSV, or Excel.

### Data fields

| Field | Description |
|---|---|
| `unitId` | Stable identifier for the translated item |
| `kind` | What was translated: `text`, `record`, `page` or `file` |
| `source` | Page URL, file URL, dataset ID, or `input` |
| `targetLanguage` | Language code for this row |
| `targetLanguageName` | Human readable language name |
| `sourceText` | The original text, or the item's leading field |
| `translatedText` | The translation |
| `metaDescription` | Translated meta description (Website mode) |
| `content` | Translated page body text (Website mode) |
| `fileUrl` | Download link for the rebuilt file or translated page |
| `wordCount` | Approximate source word count |
| `segmentCount` | How many separate strings the item held |
| `cacheHits` | Segments reused from cache, so not re-sent to the model |
| `billedItems` | How many translated-item events this row was charged |
| `error` | Error message, or `null` on success |

### How much does it cost to translate in bulk?

There are **two separate charges**, and it is worth understanding both before your first big run.

**1. This Actor charges for output.** Pay-per-event: one event per translated item, one per translated page, and one per rebuilt file. Files also charge per record inside them, so a spreadsheet row, a subtitle cue or a PDF paragraph costs the same as a dataset record. Nothing else. There is no token meter and no word meter here.

**2. Model usage is billed separately, not by this Actor.** The AI model is run by Apify's OpenRouter integration and charged directly to your Apify account at the model's own rates. Every model in the dropdown shows its real per-million-token price so you can see what you are choosing. Pick a cheap flash-class model and this is a rounding error; pick a top-end model and it is the bulk of your bill.

> **Free Plan warning:** the model integration charges roughly **10x** on the Free Plan compared to paid plans, for exactly the same model. If you plan to translate at any volume, an [Apify plan](https://apify.com/pricing?fpr=youssef) pays for itself almost immediately. Alternatively, supply your own OpenRouter API key and pay OpenRouter directly at their normal rates.

Two things keep the total down either way:

- **Cache hits cost no model tokens.** Translations are remembered across runs on your account, so re-running a catalog where only 5% of descriptions changed sends only that 5% to the model. The Actor's own per-item fee still applies to every row it writes.
- **Failed segments are never re-sent.** A string that could not be translated falls back to its source text rather than burning more tokens on retries.

Free Plan users can also translate at most 10 items into 1 language per run, with a 2 page crawl cap, which is enough to check quality before committing.

### Tips

- **Set `fields` explicitly** when translating datasets or spreadsheets. Auto-detection skips IDs, URLs and SKUs, but naming the columns you want is faster and cheaper.
- **Use the glossary** for every brand and product name. It costs nothing and prevents the single most common localization embarrassment.
- **Pick `marketing` tone** for ecommerce copy and `technical` for documentation. The default `neutral` is fine for data.
- **Schedule it.** Because of the cache, a nightly or weekly run over a changing catalog stays cheap.
- **Lower `concurrency`** if you see rate-limit warnings in the log, and raise it for large jobs.

### FAQ

**Do I need an API key?**
No. There is no OpenAI, Anthropic, Google, DeepL or Lingo key to create. Model usage is billed through your Apify account by Apify's OpenRouter integration, separately from this Actor's own output charges.

**Can I bring my own API key?**
Yes, optionally. Paste an OpenRouter key into the **OpenRouter API key** field and translation calls go straight to OpenRouter, billed on your own OpenRouter account at their normal rates instead of through Apify. This is especially worth doing on the Free Plan, where the Apify model integration charges around 10x. Leave the field empty and everything works with no key at all.

**Which languages are supported?**
Any language the underlying model handles, which covers 40+ common languages including German, French, Spanish, Italian, Portuguese, Brazilian Portuguese, Dutch, Polish, Japanese, Korean, Chinese, Arabic, Hindi and Turkish. Pass a standard language code.

**Can it translate PDFs?**
Yes, PDFs with a real text layer. Text is extracted per page and the translation comes back as plain text with page markers, **not** as a rebuilt PDF: re-flowing translated text into a fixed layout produces worse output than clean text, since translations change length. Scanned or image-only PDFs are rejected with a clear message rather than silently charged, because they need OCR first.

**What happens if I pass an unsupported file type?**
It is skipped with a warning naming the supported formats. The Actor will not read an unknown binary as text, so you are never charged for garbled output.

**Will it break my HTML or template variables?**
No. Tags, `{{variables}}`, `${literals}`, `%s` format strings, URLs and emails are masked before translation and restored afterwards. If a placeholder does not survive, that segment is retried and then left as the source text rather than shipped broken.

**Can I translate the output of another Actor?**
Yes, and this is the fastest way to use it. Run any Store Actor, copy its dataset ID from the run's Storage tab, then run this Actor in Dataset mode against that ID.

**Is this a Weglot or DeepL API alternative?**
It solves a similar problem without a monthly subscription or an API key. It translates data and files rather than serving a live translated site, so it fits catalog, dataset, subtitle and content workflows rather than real-time page serving.

**Can an AI agent call this Actor?**
Yes. It is callable through the Apify MCP server, so agents can translate scraped content as a step in a larger workflow.

**Is web scraping legal?**
Scraping publicly available data is generally legal. This Actor only reads pages you point it at, and you are responsible for complying with the terms of the sites you crawl and with copyright and data protection law in your jurisdiction. Do not translate and republish content you do not have the rights to.

**Something is wrong or missing.**
Open a ticket on the **Issues** tab and it will be looked at.

### Support

⚡ Unlock full limits by subscribing to an [Apify plan](https://apify.com/pricing?fpr=youssef).
💼 Need a custom solution? Reach out at youssefarhan24@gmail.com
🌐 Got a site in mind? [Suggest it here](https://automationbyexperts.com/apify)

# Actor input Schema

## `mode` (type: `string`):

Pick where the text comes from. Only the fields for the mode you pick are used, so you can ignore the rest.

## `targetLanguages` (type: `array`):

Pick one or more languages. Every item is translated into each language you select.

⚡ Unlock full pages and higher limits by subscribing to an [Apify plan](https://apify.com/pricing?fpr=youssef).
💼 Need a custom solution? Reach out at youssefarhan24@gmail.com
🌐 Got a site in mind? [Suggest it here](https://automationbyexperts.com/apify)

## `texts` (type: `array`):

The strings to translate. One entry per line.

## `datasetId` (type: `string`):

Pick a dataset produced by any other Actor run, and its text fields get translated.

## `startUrls` (type: `array`):

Pages to translate. The crawler stays on the same domain.

## `fileUrls` (type: `array`):

Direct links to the files to translate. Supported: .pdf, .csv, .tsv, .json, .xlsx, .srt, .vtt, .md, .markdown, .txt. Anything else is skipped rather than guessed at. Scanned or image-only PDFs are rejected: they have no text layer to translate.

## `uploadedFile` (type: `string`):

Upload a file straight from your computer instead of hosting it somewhere. Same formats as above. Use the URL list when you have several files.

## `fields` (type: `array`):

Which columns or fields to translate in Dataset, CSV, JSON and XLSX input. Leave empty to auto-detect: text fields are translated, and IDs, URLs, SKUs and numbers are left alone.

## `glossary` (type: `array`):

Brand names, product names, SKUs and anything else that must survive untouched.

## `tone` (type: `string`):

How the translation should read.

## `model` (type: `string`):

Which AI model does the translating. Prices in brackets are the model's own per-million-token rates, charged separately from this Actor: model usage is billed by Apify's OpenRouter integration (or by OpenRouter directly if you supply your own key below). This Actor only charges for the output it produces. Note that on the Free Plan the model integration charges around 10x what paid plans pay, so an Apify plan pays for itself quickly. Cheap flash-class models handle product data, UI strings and metadata well; pricier ones read better for marketing and long-form copy.

## `maxItems` (type: `integer`):

Safety cap on how many strings, dataset items or files are translated in one run.

## `maxPages` (type: `integer`):

How many pages to crawl and translate.

## `followLinks` (type: `boolean`):

Crawl links found on the start URLs. Turn off to translate only the URLs you listed.

## `maxSubtitleChars` (type: `integer`):

Translations run longer than English, so subtitle cues are re-wrapped to this width. Set to 0 to leave line breaks alone.

## `reuseCache` (type: `boolean`):

Keeps a translation cache on your account so a re-run only pays for strings that actually changed. Turn it off to force a fresh translation of everything.

## `concurrency` (type: `integer`):

How many translation requests run at once. Raise it for speed, lower it if you hit rate limits.

## `maxRetries` (type: `integer`):

Retries per failed translation request.

## `customModel` (type: `string`):

Optional. Override the Quality preset with a specific model ID.

## `apifyToken` (type: `string`):

Optional. Only needed when running this Actor locally. On the Apify platform it is filled in automatically.

## `openrouterApiKey` (type: `string`):

Optional. Bring your own OpenRouter key and translation calls go straight to OpenRouter, billed by them on your own OpenRouter account instead of through Apify. Useful on the Free Plan, where the Apify model integration charges around 10x. Leave empty to use the built-in access, which needs no key at all.

## Actor input object example

```json
{
  "mode": "text",
  "targetLanguages": [
    "de"
  ],
  "texts": [
    "Hand-poured soy candle with a warm vanilla scent.",
    "Free shipping on orders over 50 EUR."
  ],
  "startUrls": [
    "https://example.com"
  ],
  "fields": [
    "title",
    "description"
  ],
  "tone": "neutral",
  "model": "google/gemini-2.5-flash",
  "maxItems": 1000,
  "maxPages": 25,
  "followLinks": true,
  "maxSubtitleChars": 42,
  "reuseCache": true,
  "concurrency": 5,
  "maxRetries": 3
}
```

# Actor output Schema

## `translations` (type: `string`):

Every translated item, one row per item and target language. Switch between the Overview and Side by side views in the table.

## `files` (type: `string`):

Rebuilt CSV, XLSX, JSON, SRT, VTT, Markdown and TXT files, and translated page text, ready to download.

## `summary` (type: `string`):

Counts of items translated, words charged and cached translations reused.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "texts": [
        "Hand-poured soy candle with a warm vanilla scent.",
        "Free shipping on orders over 50 EUR."
    ],
    "startUrls": [
        "https://example.com"
    ],
    "fields": [
        "title",
        "description"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("fayoussef/bulk-ai-translator").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "texts": [
        "Hand-poured soy candle with a warm vanilla scent.",
        "Free shipping on orders over 50 EUR.",
    ],
    "startUrls": ["https://example.com"],
    "fields": [
        "title",
        "description",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("fayoussef/bulk-ai-translator").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "texts": [
    "Hand-poured soy candle with a warm vanilla scent.",
    "Free shipping on orders over 50 EUR."
  ],
  "startUrls": [
    "https://example.com"
  ],
  "fields": [
    "title",
    "description"
  ]
}' |
apify call fayoussef/bulk-ai-translator --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=fayoussef/bulk-ai-translator",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Bulk AI Translator: Website, Files & Datasets (No API Key)",
        "description": "Translate product catalogs, websites, datasets, CSV/XLSX/JSON files and SRT/VTT subtitles into 40+ languages. AI translation with brand-term locking and HTML/placeholder safety. No API key, and repeat runs only pay for what changed.",
        "version": "0.1",
        "x-build-id": "z56WiiCiSgL2bGVAD"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/fayoussef~bulk-ai-translator/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-fayoussef-bulk-ai-translator",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/fayoussef~bulk-ai-translator/runs": {
            "post": {
                "operationId": "runs-sync-fayoussef-bulk-ai-translator",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/fayoussef~bulk-ai-translator/run-sync": {
            "post": {
                "operationId": "run-sync-fayoussef-bulk-ai-translator",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "mode",
                    "targetLanguages"
                ],
                "properties": {
                    "mode": {
                        "title": "What do you want to translate?",
                        "enum": [
                            "text",
                            "dataset",
                            "website",
                            "file"
                        ],
                        "type": "string",
                        "description": "Pick where the text comes from. Only the fields for the mode you pick are used, so you can ignore the rest.",
                        "default": "text"
                    },
                    "targetLanguages": {
                        "title": "Translate into",
                        "uniqueItems": true,
                        "type": "array",
                        "description": "Pick one or more languages. Every item is translated into each language you select.\n\n⚡ Unlock full pages and higher limits by subscribing to an [Apify plan](https://apify.com/pricing?fpr=youssef).\n💼 Need a custom solution? Reach out at youssefarhan24@gmail.com\n🌐 Got a site in mind? [Suggest it here](https://automationbyexperts.com/apify)",
                        "items": {
                            "type": "string",
                            "enum": [
                                "ar",
                                "bn",
                                "pt-br",
                                "bg",
                                "zh",
                                "zh-tw",
                                "hr",
                                "cs",
                                "da",
                                "nl",
                                "en",
                                "et",
                                "fi",
                                "fr",
                                "de",
                                "el",
                                "he",
                                "hi",
                                "hu",
                                "id",
                                "it",
                                "ja",
                                "ko",
                                "lv",
                                "lt",
                                "ms",
                                "no",
                                "fa",
                                "pl",
                                "pt",
                                "ro",
                                "ru",
                                "sr",
                                "sk",
                                "sl",
                                "es",
                                "sv",
                                "th",
                                "tr",
                                "uk",
                                "ur",
                                "vi"
                            ],
                            "enumTitles": [
                                "Arabic (ar)",
                                "Bengali (bn)",
                                "Brazilian Portuguese (pt-br)",
                                "Bulgarian (bg)",
                                "Chinese (Simplified) (zh)",
                                "Chinese (Traditional) (zh-tw)",
                                "Croatian (hr)",
                                "Czech (cs)",
                                "Danish (da)",
                                "Dutch (nl)",
                                "English (en)",
                                "Estonian (et)",
                                "Finnish (fi)",
                                "French (fr)",
                                "German (de)",
                                "Greek (el)",
                                "Hebrew (he)",
                                "Hindi (hi)",
                                "Hungarian (hu)",
                                "Indonesian (id)",
                                "Italian (it)",
                                "Japanese (ja)",
                                "Korean (ko)",
                                "Latvian (lv)",
                                "Lithuanian (lt)",
                                "Malay (ms)",
                                "Norwegian (no)",
                                "Persian (fa)",
                                "Polish (pl)",
                                "Portuguese (pt)",
                                "Romanian (ro)",
                                "Russian (ru)",
                                "Serbian (sr)",
                                "Slovak (sk)",
                                "Slovenian (sl)",
                                "Spanish (es)",
                                "Swedish (sv)",
                                "Thai (th)",
                                "Turkish (tr)",
                                "Ukrainian (uk)",
                                "Urdu (ur)",
                                "Vietnamese (vi)"
                            ]
                        },
                        "default": [
                            "de"
                        ]
                    },
                    "texts": {
                        "title": "Texts (Text mode)",
                        "type": "array",
                        "description": "The strings to translate. One entry per line.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "datasetId": {
                        "title": "Dataset (Dataset mode)",
                        "type": "string",
                        "description": "Pick a dataset produced by any other Actor run, and its text fields get translated."
                    },
                    "startUrls": {
                        "title": "Start URLs (Website mode)",
                        "type": "array",
                        "description": "Pages to translate. The crawler stays on the same domain.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "fileUrls": {
                        "title": "File URLs (File mode)",
                        "type": "array",
                        "description": "Direct links to the files to translate. Supported: .pdf, .csv, .tsv, .json, .xlsx, .srt, .vtt, .md, .markdown, .txt. Anything else is skipped rather than guessed at. Scanned or image-only PDFs are rejected: they have no text layer to translate.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "uploadedFile": {
                        "title": "Or upload a file (File mode)",
                        "type": "string",
                        "description": "Upload a file straight from your computer instead of hosting it somewhere. Same formats as above. Use the URL list when you have several files."
                    },
                    "fields": {
                        "title": "Fields to translate",
                        "type": "array",
                        "description": "Which columns or fields to translate in Dataset, CSV, JSON and XLSX input. Leave empty to auto-detect: text fields are translated, and IDs, URLs, SKUs and numbers are left alone.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "glossary": {
                        "title": "Never translate these terms",
                        "type": "array",
                        "description": "Brand names, product names, SKUs and anything else that must survive untouched.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "tone": {
                        "title": "Tone",
                        "enum": [
                            "neutral",
                            "formal",
                            "casual",
                            "marketing",
                            "technical"
                        ],
                        "type": "string",
                        "description": "How the translation should read.",
                        "default": "neutral"
                    },
                    "model": {
                        "title": "Model",
                        "enum": [
                            "anthropic/claude-opus-5-fast",
                            "anthropic/claude-opus-5",
                            "anthropic/claude-sonnet-5",
                            "anthropic/claude-opus-4.8-fast",
                            "anthropic/claude-opus-4.8",
                            "anthropic/claude-opus-4.7-fast",
                            "anthropic/claude-opus-4.7",
                            "anthropic/claude-sonnet-4.6",
                            "anthropic/claude-opus-4.6",
                            "anthropic/claude-opus-4.5",
                            "anthropic/claude-haiku-4.5",
                            "anthropic/claude-sonnet-4.5",
                            "anthropic/claude-opus-4.1",
                            "anthropic/claude-opus-4",
                            "anthropic/claude-sonnet-4",
                            "anthropic/claude-3-haiku",
                            "anthropic/claude-fable-5",
                            "google/gemini-3.6-flash",
                            "google/gemini-3.5-flash-lite",
                            "google/gemini-3.5-flash",
                            "google/gemini-3.1-flash-lite",
                            "google/gemini-3.1-flash-lite-preview",
                            "google/gemini-3.1-pro-preview-customtools",
                            "google/gemini-3.1-pro-preview",
                            "google/gemini-3-flash-preview",
                            "google/gemini-2.5-flash-lite",
                            "google/gemini-2.5-flash",
                            "google/gemini-2.5-pro",
                            "google/gemini-2.5-pro-preview",
                            "google/gemini-2.5-pro-preview-05-06",
                            "google/gemma-4-26b-a4b-it",
                            "google/gemma-4-31b-it",
                            "google/gemma-3n-e4b-it",
                            "google/gemma-3-4b-it",
                            "google/gemma-3-12b-it",
                            "google/gemma-3-27b-it",
                            "google/gemma-2-27b-it",
                            "google/gemma-4-26b-a4b-it:free",
                            "google/gemma-4-31b-it:free",
                            "openai/gpt-5.6-luna-pro",
                            "openai/gpt-5.6-luna",
                            "openai/gpt-5.6-terra-pro",
                            "openai/gpt-5.6-terra",
                            "openai/gpt-5.6-sol-pro",
                            "openai/gpt-5.6-sol",
                            "openai/gpt-5.5-pro",
                            "openai/gpt-5.5",
                            "openai/gpt-5.4-nano",
                            "openai/gpt-5.4-mini",
                            "openai/gpt-5.4-pro",
                            "openai/gpt-5.4",
                            "openai/gpt-5.3-chat",
                            "openai/gpt-5.3-codex",
                            "openai/gpt-5.2-codex",
                            "openai/gpt-5.2-chat",
                            "openai/gpt-5.2-pro",
                            "openai/gpt-5.2",
                            "openai/gpt-5.1-codex-max",
                            "openai/gpt-5.1",
                            "openai/gpt-5.1-chat",
                            "openai/gpt-5.1-codex",
                            "openai/gpt-5.1-codex-mini",
                            "openai/o3-deep-research",
                            "openai/o4-mini-deep-research",
                            "openai/gpt-5-pro",
                            "openai/gpt-5-codex",
                            "openai/gpt-5-chat",
                            "openai/gpt-5",
                            "openai/gpt-5-mini",
                            "openai/gpt-5-nano",
                            "openai/o3-pro",
                            "openai/o4-mini-high",
                            "openai/o3",
                            "openai/o4-mini",
                            "openai/gpt-4.1",
                            "openai/gpt-4.1-mini",
                            "openai/gpt-4.1-nano",
                            "openai/gpt-4o-mini-search-preview",
                            "openai/gpt-4o-search-preview",
                            "openai/o3-mini-high",
                            "openai/o3-mini",
                            "openai/gpt-4o-2024-11-20",
                            "openai/gpt-4o-2024-08-06",
                            "openai/gpt-4o-mini",
                            "openai/gpt-4o-mini-2024-07-18",
                            "openai/gpt-4o",
                            "openai/gpt-4o-2024-05-13",
                            "openai/gpt-4-turbo",
                            "openai/gpt-4-turbo-preview",
                            "openai/gpt-4",
                            "openai/gpt-chat-latest",
                            "openai/gpt-oss-120b",
                            "openai/gpt-oss-20b",
                            "openai/o1-pro",
                            "openai/o1",
                            "openai/gpt-3.5-turbo-0613",
                            "openai/gpt-3.5-turbo-instruct",
                            "openai/gpt-3.5-turbo-16k",
                            "openai/gpt-3.5-turbo",
                            "openai/gpt-oss-20b:free",
                            "deepseek/deepseek-v3.2",
                            "deepseek/deepseek-v3.2-exp",
                            "deepseek/deepseek-v3.1-terminus",
                            "deepseek/deepseek-chat-v3.1",
                            "deepseek/deepseek-r1-0528",
                            "deepseek/deepseek-chat-v3-0324",
                            "deepseek/deepseek-r1-distill-llama-70b",
                            "deepseek/deepseek-r1",
                            "deepseek/deepseek-chat",
                            "deepseek/deepseek-v4-pro",
                            "deepseek/deepseek-v4-flash",
                            "x-ai/grok-4.5",
                            "x-ai/grok-4.3",
                            "x-ai/grok-4.20-multi-agent",
                            "x-ai/grok-4.20",
                            "x-ai/grok-build-0.1",
                            "meta-llama/llama-4-maverick",
                            "meta-llama/llama-4-scout",
                            "meta-llama/llama-3.3-70b-instruct",
                            "meta-llama/llama-3.2-1b-instruct",
                            "meta-llama/llama-3.2-3b-instruct",
                            "meta-llama/llama-3.1-70b-instruct",
                            "meta-llama/llama-3.1-8b-instruct",
                            "qwen/qwen3.7-plus",
                            "qwen/qwen3.7-max",
                            "qwen/qwen3.5-plus-20260420",
                            "qwen/qwen3.6-flash",
                            "qwen/qwen3.6-35b-a3b",
                            "qwen/qwen3.6-max-preview",
                            "qwen/qwen3.6-27b",
                            "qwen/qwen3.6-plus",
                            "qwen/qwen3.5-9b",
                            "qwen/qwen3.5-35b-a3b",
                            "qwen/qwen3.5-27b",
                            "qwen/qwen3.5-122b-a10b",
                            "qwen/qwen3.5-flash-02-23",
                            "qwen/qwen3.5-plus-02-15",
                            "qwen/qwen3.5-397b-a17b",
                            "qwen/qwen3-max-thinking",
                            "qwen/qwen3-coder-next",
                            "qwen/qwen3-vl-32b-instruct",
                            "qwen/qwen3-vl-8b-thinking",
                            "qwen/qwen3-vl-8b-instruct",
                            "qwen/qwen3-vl-30b-a3b-thinking",
                            "qwen/qwen3-vl-30b-a3b-instruct",
                            "qwen/qwen3-vl-235b-a22b-thinking",
                            "qwen/qwen3-vl-235b-a22b-instruct",
                            "qwen/qwen3-max",
                            "qwen/qwen3-coder-plus",
                            "qwen/qwen3-coder-flash"
                        ],
                        "type": "string",
                        "description": "Which AI model does the translating. Prices in brackets are the model's own per-million-token rates, charged separately from this Actor: model usage is billed by Apify's OpenRouter integration (or by OpenRouter directly if you supply your own key below). This Actor only charges for the output it produces. Note that on the Free Plan the model integration charges around 10x what paid plans pay, so an Apify plan pays for itself quickly. Cheap flash-class models handle product data, UI strings and metadata well; pricier ones read better for marketing and long-form copy.",
                        "default": "google/gemini-2.5-flash"
                    },
                    "maxItems": {
                        "title": "Max items",
                        "minimum": 1,
                        "type": "integer",
                        "description": "Safety cap on how many strings, dataset items or files are translated in one run.",
                        "default": 1000
                    },
                    "maxPages": {
                        "title": "Max pages (Website mode)",
                        "minimum": 1,
                        "type": "integer",
                        "description": "How many pages to crawl and translate.",
                        "default": 25
                    },
                    "followLinks": {
                        "title": "Follow links (Website mode)",
                        "type": "boolean",
                        "description": "Crawl links found on the start URLs. Turn off to translate only the URLs you listed.",
                        "default": true
                    },
                    "maxSubtitleChars": {
                        "title": "Max characters per subtitle line",
                        "minimum": 0,
                        "type": "integer",
                        "description": "Translations run longer than English, so subtitle cues are re-wrapped to this width. Set to 0 to leave line breaks alone.",
                        "default": 42
                    },
                    "reuseCache": {
                        "title": "Reuse translations from previous runs",
                        "type": "boolean",
                        "description": "Keeps a translation cache on your account so a re-run only pays for strings that actually changed. Turn it off to force a fresh translation of everything.",
                        "default": true
                    },
                    "concurrency": {
                        "title": "Concurrency",
                        "minimum": 1,
                        "maximum": 20,
                        "type": "integer",
                        "description": "How many translation requests run at once. Raise it for speed, lower it if you hit rate limits.",
                        "default": 5
                    },
                    "maxRetries": {
                        "title": "Max retries",
                        "minimum": 0,
                        "maximum": 8,
                        "type": "integer",
                        "description": "Retries per failed translation request.",
                        "default": 3
                    },
                    "customModel": {
                        "title": "Custom model",
                        "type": "string",
                        "description": "Optional. Override the Quality preset with a specific model ID."
                    },
                    "apifyToken": {
                        "title": "Apify token",
                        "type": "string",
                        "description": "Optional. Only needed when running this Actor locally. On the Apify platform it is filled in automatically."
                    },
                    "openrouterApiKey": {
                        "title": "OpenRouter API key",
                        "type": "string",
                        "description": "Optional. Bring your own OpenRouter key and translation calls go straight to OpenRouter, billed by them on your own OpenRouter account instead of through Apify. Useful on the Free Plan, where the Apify model integration charges around 10x. Leave empty to use the built-in access, which needs no key at all."
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
