For quick conversions, use our simple REST endpoint that returns the converted file directly.
For production applications, use our async job-based API that handles large files and provides progress updates.
queued
- Job is waiting to startin_progress
- Job is currently processingsuccess
- Job completed successfullyfailed
- Job failed with error/api/convert
Simple REST endpoint for quick conversions
/api/convert/jobs
Start a conversion job (async)
/api/convert/jobs/{id}
Check job status
/api/convert/jobs/{id}/download
Download converted file
Verify your API token is correct and hasn't expired. Ensure you're including the "Bearer " prefix.
Compress your model file or use a more efficient format. Consider splitting large models.
Check the supported formats list and verify the file extension matches the actual format.
curl https://convert3d.org/api/convert \
-F file=@damaged-helmet.glb \
-F from_format=glb \
-F to_format=usdz \
-H "Authorization: Token %your token here%" \
-o damaged-helmet.usdz
{
"success":false,
"error":"Conversion failed"
}
POST /api/convert/jobs
Authorization: Bearer YOUR_API_TOKEN
Content-Type: multipart/form-data
{
"file": [your-3d-model-file],
"from": "obj",
"to": "glb"
}
{
"id": "abc123def456",
"status": "queued",
"progress": 0
}
{
"error": "Missing 'file' field"
}
{
"error": "Missing 'api_token'"
}
GET /api/convert/jobs/{job-id}
Authorization: Bearer YOUR_API_TOKEN
{
"id": "abc123def456",
"status": "success",
"progress": 100,
"message": "Conversion completed",
"signedUrl": "https://storage.convert3d.org/converted/1234567890-model.glb?signature=..."
}
{
"id": "abc123def456",
"status": "in_progress",
"progress": 45,
"message": "Converting model..."
}
{
"id": "abc123def456",
"status": "failed",
"progress": 0,
"message": "Unsupported file format"
}
GET /api/convert/jobs/{job-id}/download
Authorization: Bearer YOUR_API_TOKEN
{
"url": "https://storage.convert3d.org/converted/1234567890-model.glb?signature=..."
}
Not ready
Not found
// Convert 3D model using Convert3D API
async function convertModel(file, apiToken) {
const formData = new FormData();
formData.append('file', file);
formData.append('from', file.name.split('.').pop().toLowerCase());
formData.append('to', 'glb');
// Start conversion job
const jobResponse = await fetch('/api/convert/jobs', {
method: 'POST',
headers: {
'Authorization': `Bearer ${apiToken}`,
},
body: formData,
});
const job = await jobResponse.json();
// Poll for completion
const pollStatus = async () => {
const statusResponse = await fetch(`/api/convert/jobs/${job.id}`, {
headers: {
'Authorization': `Bearer ${apiToken}`,
},
});
const status = await statusResponse.json();
if (status.status === 'success' && status.signedUrl) {
// Update model-viewer src
const modelViewer = document.querySelector('model-viewer');
modelViewer.src = status.signedUrl;
} else if (status.status === 'queued' || status.status === 'in_progress') {
setTimeout(pollStatus, 2000); // Poll every 2 seconds
}
};
pollStatus();
}
// Usage
const fileInput = document.getElementById('file-input');
const apiToken = 'YOUR_API_TOKEN';
fileInput.addEventListener('change', (e) => {
const file = e.target.files[0];
if (file) {
convertModel(file, apiToken);
}
});
// Install: npm install @google/model-viewer
import { useEffect, useState } from 'react';
export default function ModelViewerComponent({ modelUrl }) {
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
// Load model-viewer script
const script = document.createElement('script');
script.type = 'module';
script.src = 'https://unpkg.com/@google/model-viewer/dist/model-viewer.min.js';
document.head.appendChild(script);
return () => {
document.head.removeChild(script);
};
}, []);
return (
<div>
{isLoading && <div>Converting model...</div>}
<model-viewer
src={modelUrl}
alt="3D Model"
auto-rotate
camera-controls
shadow-intensity="1"
environment-image="neutral"
style={{ width: '100%', height: '400px' }}
/>
</div>
);
}
<!DOCTYPE html>
<html>
<head>
<script type="module" src="https://unpkg.com/@google/model-viewer/dist/model-viewer.min.js"></script>
</head>
<body>
<model-viewer
src="YOUR_CONVERTED_MODEL_URL"
alt="3D Model"
auto-rotate
camera-controls
shadow-intensity="1"
environment-image="neutral"
style="width: 100%; height: 400px;">
</model-viewer>
</body>
</html>
curl https://convert3d.org/api/convert \
-F file=@damaged-helmet.glb \
-F from_format=glb \
-F to_format=usdz \
-H "Authorization: Token %your token here%" \
-o damaged-helmet.usdz