Bulk H1 Translator
Translate H1 headings to English in bulk via any OpenAI-compatible API.
#about
Reads a CSV with H1 and Language columns (defaults match Screaming Frog exports: H1-1, Language) and translates each H1 to English row by row.
Uses structured JSON schema responses (response_format with json_schema) and retries up to 5 times per row.
Works with a local Ollama endpoint (default base URL http://localhost:11434/v1) or the OpenAI API.
Already-English and empty H1s are returned unchanged.
Requires an API key
- Platform
- Python script (requires Python 3.x)
- Input
- CSV with an H1 column and a Language column (Screaming Frog format works out of the box)API endpoint URL and optional API key
- Output
- CSV with all original columns plus a translated_h1 column containing the English translation of each H1.
- Category
- Content
Use cases
- Preparing international crawl exports for English-language analysis
- Auditing hreflang H1 consistency across locales
- Pre-processing multilingual title data before keyword mapping
#features
- Any OpenAI-compatible endpoint (Ollama local default, or OpenAI API)
- Structured JSON schema response format for reliable parsing
- Retries per row (1-5, default 3) with 1-second backoff
- Column mapping defaults to Screaming Frog H1-1 and Language
- Preserves all original CSV columns in output
- Error count reported separately from successful translations
#how-to-use
- Set the base URL in the sidebar (Ollama default or OpenAI)
- Enter the model name and optional API key
- Upload your CSV and map the H1 and Language columns
- Click Translate H1s
- Review the translated_h1 column in the results
- Download the full CSV with translations
#faq
- Does this require an OpenAI API key?
- Only if you use the OpenAI endpoint. By default it points at http://localhost:11434/v1 (Ollama running locally), which accepts any placeholder API key value. To use OpenAI, change the base URL to https://api.openai.com/v1 and enter your real key.
- What happens to H1s that are already in English?
- The prompt instructs the model to return them unchanged. The system prompt plus the response format mean you still get a JSON object back, but the translated_h1 field will contain the original English text.
- How does it handle rows that fail?
- Each row is retried up to the configured retry count (1-5, default 3) with a 1-second pause between attempts. If all retries fail, the translated_h1 value is set to an error string starting with 'Error:'. The final error count is shown in the results summary.
- What column names does it expect?
- It defaults to Screaming Frog column names (H1-1 for the heading, Language for the source language) but both columns are mappable via dropdown selectors. Any CSV column can be chosen.
- Does it process all rows in one API call?
- No. Each row is an individual API call with structured JSON schema response format. This means cost scales linearly with row count, but each translation is isolated so a single failure does not lose other results.
/contact
Want me to run this for you? I run this tool as a managed service, or build something custom around your data. You get the insights without touching the code.