Bulk H1 Translator
Use cases
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.
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.
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
- 1 Set the base URL in the sidebar (Ollama default or OpenAI)
- 2 Enter the model name and optional API key
- 3 Upload your CSV and map the H1 and Language columns
- 4 Click Translate H1s
- 5 Review the translated_h1 column in the results
- 6 Download the full CSV with translations
Frequently asked questions
- 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.
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.
Related Tools
Automatically identify the best CSS selector for a page's main content using an LLM, then extract as Markdown.
Tag customer reviews with a one or two-word topic label using OpenAI GPT models in batches.
Discover which descriptive words competitors use in titles that you are missing.
Extract content blocks and XPath patterns using Claude Haiku for template analysis.
Find cannibalising pages by clustering queries that share SERP URLs.
Generate correct hreflang tags for international SEO.
Need something built for your business?
This tool started as bespoke client work. I build custom scripts, data pipelines, and full apps for SEO and product data problems that off-the-shelf tools don't solve.
Tell Me What You Need