PDF Translation Service API

The Ltranslate PDF Translation Service provides comprehensive API support for PDF document translation, including file upload, automatic translation, task queue processing, and more.

Quick Start

Base URL

https://api.ltranslate.cn/v1

Authentication

All API requests require authentication using your API key:

Authorization: Bearer YOUR_API_KEY

API Endpoints

Upload PDF for Translation

POST /pdf/translate

Request Parameters
Parameter Type Required Description
file File Yes PDF file to translate (max 50MB)
source_lang String Yes Source language code (e.g., "en", "zh-cn")
target_lang String Yes Target language code (e.g., "zh-cn", "en")
preserve_format Boolean No Preserve original formatting (default: true)
callback_url String No URL to receive completion notification
Response
{ "success": true, "task_id": "pdf_translate_1234567890", "status": "processing", "estimated_time": 120, "file_size": 2048576, "pages": 15 }

Check Translation Status

GET /pdf/status/{task_id}

Response
{ "success": true, "task_id": "pdf_translate_1234567890", "status": "completed", "progress": 100, "created_at": "2025-12-10T10:00:00Z", "completed_at": "2025-12-10T10:02:30Z", "download_url": "https://api.ltranslate.cn/v1/pdf/download/pdf_translate_1234567890", "expires_at": "2025-12-10T18:00:00Z" }
Status Values
  • processing - Translation in progress
  • completed - Translation completed
  • failed - Translation failed
  • cancelled - Translation cancelled

Download Translated PDF

GET /pdf/download/{task_id}

Returns the translated PDF file. The download URL is valid for 8 hours.

Webhook Integration

Completion Notification

When a translation completes, Ltranslate sends a POST request to your callback URL:

{ "event": "translation.completed", "task_id": "pdf_translate_1234567890", "status": "completed", "download_url": "https://api.ltranslate.cn/v1/pdf/download/pdf_translate_1234567890", "expires_at": "2025-12-10T18:00:00Z", "timestamp": "2025-12-10T10:02:30Z" }
Response Requirements

Your webhook should respond with HTTP 200 status within 5 seconds.

Code Examples

JavaScript/Node.js

const FormData = require('form-data'); const fs = require('fs'); const axios = require('axios'); class PDFTranslator { constructor(apiKey) { this.apiKey = apiKey; this.baseUrl = 'https://api.ltranslate.cn/v1'; } async uploadPDF(filePath, sourceLang, targetLang) { const form = new FormData(); form.append('file', fs.createReadStream(filePath)); form.append('source_lang', sourceLang); form.append('target_lang', targetLang); form.append('preserve_format', 'true'); try { const response = await axios.post(`${this.baseUrl}/pdf/translate`, form, { headers: { ...form.getHeaders(), 'Authorization': `Bearer ${this.apiKey}` } }); return response.data; } catch (error) { console.error('Upload failed:', error.response?.data || error.message); throw error; } } async checkStatus(taskId) { try { const response = await axios.get(`${this.baseUrl}/pdf/status/${taskId}`, { headers: { 'Authorization': `Bearer ${this.apiKey}` } }); return response.data; } catch (error) { console.error('Status check failed:', error.response?.data || error.message); throw error; } } async downloadPDF(taskId, outputPath) { try { const response = await axios.get(`${this.baseUrl}/pdf/download/${taskId}`, { headers: { 'Authorization': `Bearer ${this.apiKey}` }, responseType: 'stream' }); const writer = fs.createWriteStream(outputPath); response.data.pipe(writer); return new Promise((resolve, reject) => { writer.on('finish', resolve); writer.on('error', reject); }); } catch (error) { console.error('Download failed:', error.response?.data || error.message); throw error; } } } // Usage example const translator = new PDFTranslator('YOUR_API_KEY'); // Translate PDF async function translatePDF() { try { // Upload PDF const uploadResult = await translator.uploadPDF( 'document.pdf', 'en', 'zh-cn' ); console.log('Upload successful:', uploadResult); // Check status periodically const taskId = uploadResult.task_id; let status = await translator.checkStatus(taskId); while (status.status === 'processing') { console.log(`Progress: ${status.progress}%`); await new Promise(resolve => setTimeout(resolve, 5000)); status = await translator.checkStatus(taskId); } // Download when complete if (status.status === 'completed') { await translator.downloadPDF(taskId, 'translated_document.pdf'); console.log('Translation completed and downloaded!'); } else { console.error('Translation failed:', status); } } catch (error) { console.error('Translation process failed:', error); } }

Python

import requests import time import os class PDFTranslator: def __init__(self, api_key): self.api_key = api_key self.base_url = 'https://api.ltranslate.cn/v1' self.headers = { 'Authorization': f'Bearer {api_key}' } def upload_pdf(self, file_path, source_lang, target_lang, callback_url=None): """Upload PDF for translation""" url = f'{self.base_url}/pdf/translate' with open(file_path, 'rb') as f: files = {'file': f} data = { 'source_lang': source_lang, 'target_lang': target_lang, 'preserve_format': 'true' } if callback_url: data['callback_url'] = callback_url response = requests.post(url, files=files, data=data, headers=self.headers) response.raise_for_status() return response.json() def check_status(self, task_id): """Check translation status""" url = f'{self.base_url}/pdf/status/{task_id}' response = requests.get(url, headers=self.headers) response.raise_for_status() return response.json() def download_pdf(self, task_id, output_path): """Download translated PDF""" url = f'{self.base_url}/pdf/download/{task_id}' response = requests.get(url, headers=self.headers, stream=True) response.raise_for_status() with open(output_path, 'wb') as f: for chunk in response.iter_content(chunk_size=8192): f.write(chunk) def translate_pdf(self, file_path, source_lang, target_lang, output_path): """Complete translation workflow""" # Upload PDF upload_result = self.upload_pdf(file_path, source_lang, target_lang) task_id = upload_result['task_id'] print(f"Upload successful, task ID: {task_id}") # Wait for completion while True: status = self.check_status(task_id) print(f"Status: {status['status']} ({status.get('progress', 0)}%)") if status['status'] == 'completed': break elif status['status'] == 'failed': raise Exception(f"Translation failed: {status}") time.sleep(10) # Download result self.download_pdf(task_id, output_path) print(f"Translation completed: {output_path}") # Usage example translator = PDFTranslator('YOUR_API_KEY') # Translate a PDF try: translator.translate_pdf( 'document.pdf', 'en', 'zh-cn', 'translated_document.pdf' ) except Exception as e: print(f"Translation failed: {e}")

Error Handling

Error Response Format

{ "success": false, "error": { "code": "INVALID_FILE_TYPE", "message": "Only PDF files are supported", "details": { "file_type": "image/jpeg", "supported_types": ["application/pdf"] } } }

Common Error Codes

Error Code Description HTTP Status
INVALID_API_KEY Invalid or expired API key 401
FILE_TOO_LARGE PDF file exceeds 50MB limit 413
INVALID_FILE_TYPE Only PDF files are supported 400
UNSUPPORTED_LANGUAGE Source or target language not supported 400
TASK_NOT_FOUND Task ID not found 404
QUOTA_EXCEEDED API quota exceeded 429

Rate Limiting

API requests are rate-limited based on your subscription plan:

Plan Requests/Minute Concurrent Tasks File Size Limit
Free 10 1 10MB
Business 50 5 25MB
Professional 200 20 50MB
Enterprise 2000 100 100MB

Best Practices

  • File Optimization: Optimize PDFs before upload to reduce translation time and costs
  • Error Handling: Implement robust error handling and retry logic
  • Progress Monitoring: Monitor translation progress and notify users
  • Security: Never expose API keys in client-side code
  • Testing: Test with sample PDFs before processing large documents
  • Backup: Keep original files as backups

Next Steps

Support

Need help with the PDF Translation API? Contact our support team: