March 26, 20268 min read

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.

api developers integration transliteration javascript python
Ad 336x280

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

  1. Sign up at transliterate.in
  2. Go to your account dashboard and generate an API key under Settings → API Access
  3. All API requests go to https://api.transliterate.in/v1/
  4. Include your API key as a Bearer token in the Authorization header
A quick test to confirm your key works:
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

EndpointMethodDescription
/v1/transliteratePOSTConvert Roman/phonetic text to a target Indian script
/v1/transliterate/batchPOSTConvert multiple strings in one request
/v1/convertPOSTConvert between two Indian scripts directly
/v1/suggestPOSTGet multiple word suggestions for a phonetic input
/v1/languagesGETList all supported languages and their codes
/v1/usageGETCheck your current API usage and rate limit status

Language Codes

LanguageCodeScript
HindihiDevanagari
BengalibnBengali
TamiltaTamil
TeluguteTelugu
MarathimrDevanagari
GujaratiguGujarati
KannadaknKannada
MalayalammlMalayalam
PunjabipaGurmukhi
OdiaorOdia
UrduurNastaliq
SanskritsaDevanagari

Request Parameters

/v1/transliterate

ParameterTypeRequiredDescription
textstringYesInput text in Roman/phonetic script
targetLangstringYesLanguage code (e.g., "hi", "ta")
suggestionsbooleanNoInclude alternative suggestions (default: false)
maxSuggestionsintegerNoNumber of alternatives (1-5, default: 3)
preserveNumbersbooleanNoKeep Arabic numerals as-is (default: true)
preserveEnglishbooleanNoDon't convert recognized English words (default: false)

/v1/transliterate/batch

ParameterTypeRequiredDescription
itemsarrayYesArray of {id, text, targetLang} objects
preserveNumbersbooleanNoApplied to all items (default: true)
Maximum 100 items per batch request.

/v1/convert

ParameterTypeRequiredDescription
textstringYesSource text in an Indian script
sourceLangstringYesLanguage code of the source text
targetLangstringYesLanguage 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

PlanRequests/MinuteRequests/MonthBatch Size
Free101,00010 items
Starter6020,00050 items
Pro300200,000100 items
EnterpriseCustomUnlimited500 items
When you hit a rate limit, the API returns HTTP 429 with a Retry-After header indicating when you can retry.

Error Handling

HTTP CodeError CodeMeaning
400INVALID_LANGLanguage code not recognized
400TEXT_TOO_LONGText exceeds 5,000 character limit
400BATCH_TOO_LARGEMore than max items in batch
401UNAUTHORIZEDMissing or invalid API key
429RATE_LIMITEDToo many requests; check Retry-After
500SERVER_ERRORRetry 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.

Ad 728x90