PDF Conversion API
Frontend Integration Guide
API Version 1.0.0Overview
How It Works
The PDF Conversion API uses an asynchronous task processing model. Unlike standard synchronous requests, you submit a job, get a task_id, and poll for completion.
Base URL
Production: http://YOUR_SERVER_IP:8002
Local Dev: http://localhost:8002
Interactive API Docs: http://YOUR_SERVER_IP:8002/docs
Authentication
The API is currently open — no authentication required.
Future versions will support API keys and OAuth2.
Conversion Flow
Upload File
POST /api/v1/convertReturns: task_id
Check Status
GET /api/v1/status/{id}Poll every 1-2 seconds
Download Result
GET /api/v1/download/{id}When status = completed
Status Values
| Status | Description | Action |
|---|---|---|
| pending | Task queued, waiting to start | Keep polling |
| processing | Conversion in progress | Keep polling |
| completed | Conversion successful | Download file |
| failed | Conversion error occurred | Check error message |
Available Conversions
📥 Conversions TO PDF
jpg_to_pdf → .pdfpng_to_pdf → .pdfword_to_pdf → .pdfpowerpoint_to_pdf → .pdfexcel_to_pdf → .pdfhtml_to_pdf → .pdf📤 Conversions FROM PDF
pdf_to_jpg → .jpgpdf_to_png → .pngpdf_to_word → .docxpdf_to_powerpoint → .pptxpdf_to_excel → .xlsxpdf_to_pdfa → .pdfAPI Endpoints
Check if the API is running and services are connected.
{
"status": "healthy",
"redis": "connected",
"celery": "running"
}
Retrieve all available conversion types with descriptions.
Use this to populate dropdown menus in your UI.
Get the total number of conversions performed by the system.
{
"total_conversions": 1234,
"message": "Total conversions since system deployment"
}
Upload file and start background conversion task.
Content-Type: multipart/form-data
| Field | Type | Required | Description |
|---|---|---|---|
file |
File | ✅ Yes | File to convert (max 50MB) |
conversion_type |
String | ✅ Yes | Type of conversion |
quality |
Integer | ❌ No | Output quality 1-100 (default: 95) |
dpi |
Integer | ❌ No | DPI for image conversions (default: 300) |
compress |
Boolean | ❌ No | Apply compression (default: false) |
{
"task_id": "abc-123-def-456",
"status": "pending",
"message": "Conversion task created successfully",
"created_at": "2026-01-09T12:00:00"
}
{
"detail": "File size exceeds maximum limit of 50MB"
}
Check progress and current status of a specific task.
{
"task_id": "abc-123-def-456",
"status": "pending",
"progress": 0,
"message": "Task is queued...",
"download_url": null,
"error": null
}
{
"task_id": "abc-123-def-456",
"status": "processing",
"progress": 50,
"message": "Converting file...",
"download_url": null,
"error": null
}
{
"task_id": "abc-123-def-456",
"status": "completed",
"progress": 100,
"message": "Conversion completed successfully",
"download_url": "/api/v1/download/abc-123-def-456",
"error": null
}
{
"task_id": "abc-123-def-456",
"status": "failed",
"progress": 0,
"message": "Conversion failed",
"download_url": null,
"error": "Invalid file format"
}
Download the final converted binary file.
Request Examples
async function convertFile(file, conversionType) {
// 1. Upload file
const formData = new FormData();
formData.append('file', file);
formData.append('conversion_type', conversionType);
formData.append('quality', 95);
const uploadResponse = await fetch('http://localhost:8002/api/v1/convert', {
method: 'POST',
body: formData
});
const { task_id } = await uploadResponse.json();
console.log('Task created:', task_id);
// 2. Poll for status
let status = 'pending';
while (status === 'pending' || status === 'processing') {
await new Promise(resolve => setTimeout(resolve, 2000)); // Wait 2 seconds
const statusResponse = await fetch(
`http://localhost:8002/api/v1/status/${task_id}`
);
const statusData = await statusResponse.json();
status = statusData.status;
console.log('Status:', status, 'Progress:', statusData.progress + '%');
if (status === 'failed') {
throw new Error(statusData.error);
}
}
// 3. Download result
if (status === 'completed') {
const downloadUrl = `http://localhost:8002/api/v1/download/${task_id}`;
window.location.href = downloadUrl; // Trigger download
return task_id;
}
}
// Usage
const fileInput = document.getElementById('fileInput');
const file = fileInput.files[0];
convertFile(file, 'word_to_pdf');
import { useState } from 'react';
function useFileConverter() {
const [loading, setLoading] = useState(false);
const [progress, setProgress] = useState(0);
const [error, setError] = useState(null);
const convertFile = async (file, conversionType) => {
setLoading(true);
setError(null);
setProgress(0);
try {
// Upload
const formData = new FormData();
formData.append('file', file);
formData.append('conversion_type', conversionType);
const response = await fetch('http://localhost:8002/api/v1/convert', {
method: 'POST',
body: formData
});
if (!response.ok) {
throw new Error('Upload failed');
}
const { task_id } = await response.json();
// Poll status
const checkStatus = async () => {
const statusResponse = await fetch(
`http://localhost:8002/api/v1/status/${task_id}`
);
const data = await statusResponse.json();
setProgress(data.progress);
if (data.status === 'completed') {
// Download
const downloadUrl = `http://localhost:8002/api/v1/download/${task_id}`;
const link = document.createElement('a');
link.href = downloadUrl;
link.download = `converted_file.pdf`;
link.click();
setLoading(false);
return;
}
if (data.status === 'failed') {
throw new Error(data.error || 'Conversion failed');
}
// Continue polling
setTimeout(checkStatus, 2000);
};
await checkStatus();
} catch (err) {
setError(err.message);
setLoading(false);
}
};
return { convertFile, loading, progress, error };
}
import requests
import time
def convert_file(file_path, conversion_type):
# 1. Upload file
with open(file_path, 'rb') as f:
files = {'file': f}
data = {
'conversion_type': conversion_type,
'quality': 95
}
response = requests.post(
'http://localhost:8002/api/v1/convert',
files=files,
data=data
)
task_id = response.json()['task_id']
print(f"Task created: {task_id}")
# 2. Poll for status
while True:
status_response = requests.get(
f'http://localhost:8002/api/v1/status/{task_id}'
)
status_data = status_response.json()
print(f"Status: {status_data['status']}, Progress: {status_data['progress']}%")
if status_data['status'] == 'completed':
break
elif status_data['status'] == 'failed':
raise Exception(status_data['error'])
time.sleep(2)
# 3. Download result
download_response = requests.get(
f'http://localhost:8002/api/v1/download/{task_id}'
)
with open('converted_file.pdf', 'wb') as f:
f.write(download_response.content)
print("Download complete!")
# Usage
convert_file('document.docx', 'word_to_pdf')
# 1. Convert Word to PDF
TASK_ID=$(curl -X POST "http://localhost:8002/api/v1/convert" \
-F "file=@document.docx" \
-F "conversion_type=word_to_pdf" \
| jq -r '.task_id')
echo "Task ID: $TASK_ID"
# 2. Check status (poll until completed)
while true; do
STATUS=$(curl -s "http://localhost:8002/api/v1/status/$TASK_ID" | jq -r '.status')
echo "Status: $STATUS"
if [ "$STATUS" = "completed" ]; then
break
elif [ "$STATUS" = "failed" ]; then
echo "Conversion failed!"
exit 1
fi
sleep 2
done
# 3. Download result
curl "http://localhost:8002/api/v1/download/$TASK_ID" -o converted.pdf
echo "Download complete: converted.pdf"
Error Handling
Common Errors
| Status Code | Error | Solution |
|---|---|---|
| 400 | Invalid file format | Check that file matches conversion type |
| 400 | Missing required fields | Ensure file and conversion_type are provided |
| 404 | Task not found | Task may have expired (24hr lifetime) |
| 413 | File too large | Maximum file size is 50MB |
| 500 | Internal server error | Contact API administrator |
Best Practices
- Always validate files client-side before uploading
- Implement retry logic for network errors
- Show progress indicators to users during polling
- Handle timeouts - stop polling after 2-3 minutes
- Store task_id in case user refreshes page
Rate Limits & File Size
Quick Start Checklist
- Get the API base URL from your backend team
- Test the /health endpoint to verify connectivity
- Fetch available formats from /api/v1/formats
- Implement file upload with multipart/form-data
- Add status polling with 2-second intervals
- Handle download trigger when status is completed
- Add error handling for all failure cases
- Implement progress indicators for better UX
- Add file size validation (max 50MB)
- Test with various file types and sizes