Batch Processing
Generate multiple images efficiently with Canvelete's (opens in a new tab) batch rendering API.
Overview
Batch processing allows you to render multiple designs in a single API call, which is more efficient than individual requests for large-scale generation.
Basic Batch Render
curl -X POST "https://api.canvelete.com/v1/render/batch" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"renders": [
{
"designId": "design_123",
"format": "png",
"dynamicData": {"name": "Alice"}
},
{
"designId": "design_123",
"format": "png",
"dynamicData": {"name": "Bob"}
}
]
}'Response
{
"success": true,
"data": {
"batchId": "batch_xyz789",
"status": "processing",
"totalRenders": 2,
"completedRenders": 0,
"renders": [
{"renderId": "render_001", "status": "queued"},
{"renderId": "render_002", "status": "queued"}
]
}
}Webhook Notification
Configure a webhook to receive completion notifications:
{
"renders": [...],
"webhook": "https://your-app.com/webhooks/batch-complete"
}Webhook payload:
{
"eventType": "batch.completed",
"data": {
"batchId": "batch_xyz789",
"status": "completed",
"renders": [
{
"renderId": "render_001",
"status": "completed",
"downloadUrl": "https://cdn.canvelete.com/renders/001.png"
},
{
"renderId": "render_002",
"status": "completed",
"downloadUrl": "https://cdn.canvelete.com/renders/002.png"
}
]
}
}SDK Examples
Python
from canvelete import CanveleteClient
client = CanveleteClient(api_key="YOUR_API_KEY")
# Prepare batch data
users = [
{"name": "Alice", "title": "Engineer"},
{"name": "Bob", "title": "Designer"},
{"name": "Carol", "title": "Manager"}
]
renders = [
{
"design_id": "badge_template",
"format": "png",
"dynamic_data": user
}
for user in users
]
# Execute batch
results = client.render.batch(renders)
# Process results
for result in results:
print(f"Generated: {result['downloadUrl']}")TypeScript
import { CanveleteClient } from '@canveletedotcom/sdk';
const client = new CanveleteClient({ apiKey: 'YOUR_API_KEY' });
const users = [
{ name: 'Alice', title: 'Engineer' },
{ name: 'Bob', title: 'Designer' },
{ name: 'Carol', title: 'Manager' }
];
const renders = users.map(user => ({
designId: 'badge_template',
format: 'png',
dynamicData: user
}));
const results = await client.render.batch(renders);
for (const result of results) {
console.log(`Generated: ${result.downloadUrl}`);
}Best Practices
Optimal Batch Size
| Plan | Recommended Batch Size |
|---|---|
| Free | 5-10 |
| Individual | 10-25 |
| Teams | 25-50 |
| Enterprise | 50-100 |
Parallel Processing
For very large batches, split into multiple parallel requests:
import asyncio
from canvelete import CanveleteClient
client = CanveleteClient(api_key="YOUR_API_KEY")
async def process_batch(renders):
return await client.render.batch_async(renders)
async def process_all(all_renders, batch_size=25):
batches = [
all_renders[i:i+batch_size]
for i in range(0, len(all_renders), batch_size)
]
results = await asyncio.gather(*[
process_batch(batch) for batch in batches
])
return [item for sublist in results for item in sublist]
# Process 1000 renders in parallel batches
all_results = asyncio.run(process_all(renders_list))Error Handling
Handle partial failures in batch operations:
results = client.render.batch(renders)
successful = []
failed = []
for result in results:
if result['status'] == 'completed':
successful.append(result)
else:
failed.append(result)
print(f"Completed: {len(successful)}, Failed: {len(failed)}")
# Retry failed renders
if failed:
retry_renders = [
renders[i] for i, r in enumerate(results)
if r['status'] == 'failed'
]
retry_results = client.render.batch(retry_renders)Rate Limits
| Plan | Batch Requests/Hour | Max Batch Size |
|---|---|---|
| Free | 10 | 10 |
| Individual | 100 | 25 |
| Teams | 500 | 50 |
| Enterprise | Unlimited | 100 |
Use Cases
Certificate Generation
# Generate certificates for course completions
completions = db.query("SELECT * FROM completions WHERE certificate_sent = false")
renders = [
{
"template_id": "certificate_template",
"format": "pdf",
"dynamic_data": {
"name": c.student_name,
"course": c.course_name,
"date": c.completion_date.strftime("%B %d, %Y"),
"instructor": c.instructor_name
}
}
for c in completions
]
results = client.render.batch(renders)
# Send certificates
for i, result in enumerate(results):
send_email(
to=completions[i].student_email,
subject="Your Certificate",
attachment=result['downloadUrl']
)
db.update(completions[i].id, certificate_sent=True)Product Image Generation
# Generate product cards for new inventory
products = db.query("SELECT * FROM products WHERE card_image IS NULL")
renders = [
{
"design_id": "product_card",
"format": "png",
"dynamic_data": {
"name": p.name,
"price": f"${p.price:.2f}",
"image": p.image_url,
"badge": "NEW" if p.is_new else None
}
}
for p in products
]
results = client.render.batch(renders)
# Update products with generated images
for i, result in enumerate(results):
db.update(products[i].id, card_image=result['downloadUrl'])Next Steps
- Rendering API — Full rendering documentation
- Webhooks — Async notifications
- Performance Optimization — Speed tips