Advanced Topics
Batch Processing

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

PlanRecommended Batch Size
Free5-10
Individual10-25
Teams25-50
Enterprise50-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

PlanBatch Requests/HourMax Batch Size
Free1010
Individual10025
Teams50050
EnterpriseUnlimited100

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