TranslitHub API — Add Indian Language Transliteration to Your App
A developer guide to the TranslitHub transliteration API — endpoints, authentication, rate limits, and working code examples in JavaScript and Python.
If you're building an app that needs to accept or display Indian language text, adding transliteration support isn't as complicated as it sounds. The TranslitHub API gives you a clean REST interface to convert phonetic Roman input into any major Indian script — and to convert between scripts — without you having to manage any language processing infrastructure yourself.
This guide is for developers. It covers authentication, the core endpoints, request parameters, error handling, and real working code in JavaScript and Python.
Why Add Transliteration to Your App?
A few common scenarios where the API solves a real problem:
- User-generated content: Your app needs users to type in Hindi, Tamil, or Marathi, but they're using a standard English keyboard. Instead of asking them to install input method editors, you accept their phonetic input and convert it server-side.
- Content management: You have an English database of product names, place names, or category labels that need to be rendered in regional scripts for localized versions of your site.
- Form filling: Government portal integrations, healthcare apps, and education platforms often need to accept names and addresses in both Roman and native scripts.
- Search indexing: Build a search index that accepts queries in both phonetic and native script form and returns the same results.
Getting Started
- Sign up at transliterate.in
- Go to your account dashboard and generate an API key under Settings → API Access
- All API requests go to
https://api.transliterate.in/v1/ - Include your API key as a Bearer token in the
Authorizationheader
curl -X POST https://api.transliterate.in/v1/transliterate \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"text": "namaste", "targetLang": "hi"}'
Expected response:
{
"original": "namaste",
"result": "नमस्ते",
"targetLang": "hi",
"script": "Devanagari"
}
Core Endpoints
| Endpoint | Method | Description |
|---|---|---|
/v1/transliterate | POST | Convert Roman/phonetic text to a target Indian script |
/v1/transliterate/batch | POST | Convert multiple strings in one request |
/v1/convert | POST | Convert between two Indian scripts directly |
/v1/suggest | POST | Get multiple word suggestions for a phonetic input |
/v1/languages | GET | List all supported languages and their codes |
/v1/usage | GET | Check your current API usage and rate limit status |
Language Codes
| Language | Code | Script |
|---|---|---|
| Hindi | hi | Devanagari |
| Bengali | bn | Bengali |
| Tamil | ta | Tamil |
| Telugu | te | Telugu |
| Marathi | mr | Devanagari |
| Gujarati | gu | Gujarati |
| Kannada | kn | Kannada |
| Malayalam | ml | Malayalam |
| Punjabi | pa | Gurmukhi |
| Odia | or | Odia |
| Urdu | ur | Nastaliq |
| Sanskrit | sa | Devanagari |
Request Parameters
/v1/transliterate
| Parameter | Type | Required | Description |
|---|---|---|---|
text | string | Yes | Input text in Roman/phonetic script |
targetLang | string | Yes | Language code (e.g., "hi", "ta") |
suggestions | boolean | No | Include alternative suggestions (default: false) |
maxSuggestions | integer | No | Number of alternatives (1-5, default: 3) |
preserveNumbers | boolean | No | Keep Arabic numerals as-is (default: true) |
preserveEnglish | boolean | No | Don't convert recognized English words (default: false) |
/v1/transliterate/batch
| Parameter | Type | Required | Description |
|---|---|---|---|
items | array | Yes | Array of {id, text, targetLang} objects |
preserveNumbers | boolean | No | Applied to all items (default: true) |
/v1/convert
| Parameter | Type | Required | Description |
|---|---|---|---|
text | string | Yes | Source text in an Indian script |
sourceLang | string | Yes | Language code of the source text |
targetLang | string | Yes | Language code to convert into |
Code Examples
JavaScript / Node.js — Single Transliteration
async function transliterate(text, targetLang) {
const response = await fetch('https://api.transliterate.in/v1/transliterate', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
text,
targetLang,
suggestions: true,
maxSuggestions: 3
})
});
if (!response.ok) {
const error = await response.json();
throw new Error(API error ${response.status}: ${error.message});
}
return response.json();
}
// Usage
const result = await transliterate('kaise ho aap', 'hi');
console.log(result.result); // कैसे हो आप
console.log(result.suggestions); // alternative word-level options
JavaScript — Batch Transliteration
async function transliterateBatch(items) {
const response = await fetch('https://api.transliterate.in/v1/transliterate/batch', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({ items })
});
return response.json();
}
const items = [
{ id: 'title', text: 'swaagat hai aapka', targetLang: 'hi' },
{ id: 'tagline', text: 'aage badhte raho', targetLang: 'hi' },
{ id: 'cta', text: 'abhi shuru karein', targetLang: 'hi' }
];
const results = await transliterateBatch(items);
results.items.forEach(item => {
console.log(${item.id}: ${item.result});
});
// title: स्वागत है आपका
// tagline: आगे बढ़ते रहो
// cta: अभी शुरू करें
Python — Single Transliteration
import requests
def transliterate(text, target_lang, api_key):
response = requests.post(
'https://api.transliterate.in/v1/transliterate',
headers={
'Authorization': f'Bearer {api_key}',
'Content-Type': 'application/json'
},
json={
'text': text,
'targetLang': target_lang,
'suggestions': False
}
)
response.raise_for_status()
return response.json()
result = transliterate('vanakkam', 'ta', 'YOUR_API_KEY')
print(result['result']) # வணக்கம்
Python — Script Conversion (Hindi to Marathi)
Hindi and Marathi both use Devanagari, so they share the same script. But phonological differences mean direct script conversion is sometimes useful for Transliteration between closely related scripts:
def convert_script(text, source_lang, target_lang, api_key):
response = requests.post(
'https://api.transliterate.in/v1/convert',
headers={'Authorization': f'Bearer {api_key}'},
json={
'text': text,
'sourceLang': source_lang,
'targetLang': target_lang
}
)
response.raise_for_status()
return response.json()
# Convert Bengali text to Assamese script representation
result = convert_script('আমার সোনার বাংলা', 'bn', 'or', 'YOUR_API_KEY')
print(result['result'])
React Component Example
import { useState, useEffect } from 'react';
function TransliteratingInput({ targetLang, onTransliterated }) {
const [romanInput, setRomanInput] = useState('');
const [convertedText, setConvertedText] = useState('');
const [isConverting, setIsConverting] = useState(false);
useEffect(() => {
if (!romanInput.trim()) {
setConvertedText('');
return;
}
const timer = setTimeout(async () => {
setIsConverting(true);
try {
const res = await fetch('/api/transliterate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ text: romanInput, targetLang })
});
const data = await res.json();
setConvertedText(data.result);
onTransliterated?.(data.result);
} finally {
setIsConverting(false);
}
}, 300); // debounce 300ms
return () => clearTimeout(timer);
}, [romanInput, targetLang]);
return (
<div>
<input
value={romanInput}
onChange={e => setRomanInput(e.target.value)}
placeholder="Type phonetically in English..."
/>
<p>{isConverting ? 'Converting...' : convertedText}</p>
</div>
);
}
Rate Limits
| Plan | Requests/Minute | Requests/Month | Batch Size |
|---|---|---|---|
| Free | 10 | 1,000 | 10 items |
| Starter | 60 | 20,000 | 50 items |
| Pro | 300 | 200,000 | 100 items |
| Enterprise | Custom | Unlimited | 500 items |
Retry-After header indicating when you can retry.
Error Handling
| HTTP Code | Error Code | Meaning |
|---|---|---|
| 400 | INVALID_LANG | Language code not recognized |
| 400 | TEXT_TOO_LONG | Text exceeds 5,000 character limit |
| 400 | BATCH_TOO_LARGE | More than max items in batch |
| 401 | UNAUTHORIZED | Missing or invalid API key |
| 429 | RATE_LIMITED | Too many requests; check Retry-After |
| 500 | SERVER_ERROR | Retry after a moment; contact support if persistent |
async function safeTransliterate(text, targetLang) {
const response = await fetch('https://api.transliterate.in/v1/transliterate', {
method: 'POST',
headers: {
'Authorization': Bearer ${process.env.TRANSLITHUB_API_KEY},
'Content-Type': 'application/json'
},
body: JSON.stringify({ text, targetLang })
});
if (response.status === 429) {
const retryAfter = response.headers.get('Retry-After') || '5';
await new Promise(r => setTimeout(r, parseInt(retryAfter) * 1000));
return safeTransliterate(text, targetLang); // retry once
}
if (!response.ok) {
const err = await response.json();
throw new Error(Transliteration failed: ${err.error} — ${err.message});
}
return response.json();
}
Proxying Through Your Backend
If your frontend is browser-based, don't expose your API key to the client. Proxy the request through your backend:
// Next.js API route: pages/api/transliterate.js
export default async function handler(req, res) {
if (req.method !== 'POST') return res.status(405).end();
const { text, targetLang } = req.body;
if (!text || !targetLang) {
return res.status(400).json({ error: 'text and targetLang are required' });
}
const upstream = await fetch('https://api.transliterate.in/v1/transliterate', {
method: 'POST',
headers: {
'Authorization': Bearer ${process.env.TRANSLITHUB_API_KEY},
'Content-Type': 'application/json'
},
body: JSON.stringify({ text, targetLang })
});
const data = await upstream.json();
res.status(upstream.status).json(data);
}
This keeps your API key server-side while your React/Vue/Svelte frontend calls /api/transliterate instead.
Webhook Support
For async workflows (large document conversion, batch jobs), the API supports webhooks. Include a webhookUrl in your batch request and the results POST to your endpoint when processing completes — typically within a few seconds for large batches.
{
"items": [...],
"webhookUrl": "https://yourapp.com/webhooks/transliteration"
}
The webhook payload includes the full results object plus a jobId you can use to correlate with the original request.
Related Tools
- Bulk Transliteration Tool — file upload and batch conversion without code
- Embeddable Widget — add transliteration to a website without an API
- Transliteration Editor — manual typing and export