Batch Image Generation from CSV (Guide)

Batch Image Generation from CSV (Guide)

Batch image generation from a CSV is the fastest way to turn a spreadsheet into thousands of branded images. You have 500 products, each needing an image with name, price, photo, and sale badge. Doing this by hand in Canva would take days.

I ran this exact workflow last month for an e-commerce client. 500 product images, generated in about 15 minutes from a CSV export. Here's the complete process with both code and no-code methods. All pricing is as of March 2026.

How batch csv image generation worksHow Batch CSV Image Generation Works

The process is three steps:

  1. Design a template with dynamic fields (text, images, colors)
  2. Prepare your CSV with one row per image, columns matching your template fields
  3. Loop through the CSV and call the API for each row

That's it. Each row becomes one image.

Step 1 design your templateStep 1: Design Your Template

Create a template in Imejis.io with layers that match your data. For a product catalog, that might be:

  • product_name — text layer
  • price — text layer
  • product_image — image layer
  • discount_badge — text layer (optional, for sale items)
  • background — shape with fill color

Name your layers clearly. These names become the column headers in your CSV.

Step 2 prepare your csvStep 2: Prepare Your CSV

Structure your spreadsheet so each column maps to a template layer:

product_name,price,product_image,discount_badge
Classic Runner,$29.99,https://cdn.example.com/runner.jpg,40% OFF
Urban Jacket,$89.00,https://cdn.example.com/jacket.jpg,
Wool Beanie,$15.99,https://cdn.example.com/beanie.jpg,NEW
Canvas Tote,$24.50,https://cdn.example.com/tote.jpg,25% OFF
Leather Belt,$45.00,https://cdn.example.com/belt.jpg,

A few things to get right:

  • Image URLs must be publicly accessible. The API fetches the image from the URL you provide. If it's behind authentication or on localhost, it won't work.
  • Empty cells are fine. If a product has no discount, leave the discount_badge column empty. The template layer stays as designed (or hidden, if you set it up that way).
  • Watch your encoding. Save as UTF-8 if you have special characters, accents, or non-Latin text.

Step 3 generate imagesStep 3: Generate Images

Method a nodejs scriptMethod A: Node.js Script

import fs from "fs"
import { parse } from "csv-parse/sync"
 
const API_KEY = process.env.IMEJIS_API_KEY
const TEMPLATE_ID = "YOUR_TEMPLATE_ID"
 
// Read and parse CSV
const csvData = fs.readFileSync("products.csv", "utf-8")
const rows = parse(csvData, { columns: true, skip_empty_lines: true })
 
console.log(`Processing ${rows.length} products...`)
 
for (const [index, row] of rows.entries()) {
  const payload = {
    product_name: { text: row.product_name },
    price: { text: row.price },
    product_image: { image: row.product_image },
  }
 
  // Only include discount badge if it has a value
  if (row.discount_badge) {
    payload.discount_badge = { text: row.discount_badge }
  }
 
  const response = await fetch(`https://render.imejis.io/v1/${TEMPLATE_ID}`, {
    method: "POST",
    headers: {
      "dma-api-key": API_KEY,
      "Content-Type": "application/json",
    },
    body: JSON.stringify(payload),
  })
 
  const buffer = Buffer.from(await response.arrayBuffer())
  fs.writeFileSync(`output/product_${index + 1}.png`, buffer)
 
  console.log(`Generated ${index + 1}/${rows.length}: ${row.product_name}`)
}
 
console.log("Done!")

Method b python scriptMethod B: Python Script

import csv
import requests
import os
 
API_KEY = os.environ['IMEJIS_API_KEY']
TEMPLATE_ID = 'YOUR_TEMPLATE_ID'
 
with open('products.csv', 'r') as f:
    reader = csv.DictReader(f)
    rows = list(reader)
 
print(f'Processing {len(rows)} products...')
 
for i, row in enumerate(rows):
    payload = {
        'product_name': {'text': row['product_name']},
        'price': {'text': row['price']},
        'product_image': {'image': row['product_image']}
    }
 
    if row.get('discount_badge'):
        payload['discount_badge'] = {'text': row['discount_badge']}
 
    response = requests.post(
        f'https://render.imejis.io/v1/{TEMPLATE_ID}',
        headers={
            'dma-api-key': API_KEY,
            'Content-Type': 'application/json'
        },
        json=payload
    )
 
    with open(f'output/product_{i + 1}.png', 'wb') as img:
        img.write(response.content)
 
    print(f'Generated {i + 1}/{len(rows)}: {row["product_name"]}')
 
print('Done!')

Method c no code google sheets zapierMethod C: No-Code (Google Sheets + Zapier)

If you don't want to write code:

  1. Upload your CSV to Google Sheets
  2. Create a Zap with trigger "New Spreadsheet Row in Google Sheets"
  3. Add an action: Webhooks by Zapier > POST request
  4. Configure the request:
    • URL: https://render.imejis.io/v1/YOUR_TEMPLATE_ID
    • Headers: dma-api-key: YOUR_API_KEY
    • Body: Map spreadsheet columns to JSON fields
  5. Turn on the Zap — each new row generates an image

The same approach works with Make.com or n8n. In n8n, use a Spreadsheet File node to read the CSV, then loop through rows with an HTTP Request node. For a complete walkthrough of the Google Sheets approach, see our guide on generating images from Google Sheets and uploading to Drive.

Method d airtable makeMethod D: Airtable + Make

If your data lives in Airtable:

  1. Create a Make scenario triggered by "Watch Records" in Airtable
  2. Add an HTTP module that calls the Imejis.io API
  3. Map Airtable fields to the JSON payload
  4. Optionally upload the generated image back to an Airtable attachment field

This creates a live pipeline: add a row to Airtable, get an image generated automatically.

Handling large batchesHandling Large Batches

Speed expectationsSpeed Expectations

Batch SizeSequential (1 at a time)Parallel (5 at a time)
100 images~3 minutes~40 seconds
500 images~17 minutes~3.5 minutes
1,000 images~33 minutes~7 minutes
5,000 images~2.8 hours~35 minutes

Adding parallelism nodejsAdding Parallelism (Node.js)

For large batches, run multiple requests at once:

const BATCH_SIZE = 5 // Process 5 images simultaneously
 
for (let i = 0; i < rows.length; i += BATCH_SIZE) {
  const batch = rows.slice(i, i + BATCH_SIZE)
 
  await Promise.all(
    batch.map(async (row, j) => {
      const response = await fetch(/* ... */)
      const buffer = Buffer.from(await response.arrayBuffer())
      fs.writeFileSync(`output/product_${i + j + 1}.png`, buffer)
    })
  )
 
  console.log(
    `Batch complete: ${Math.min(i + BATCH_SIZE, rows.length)}/${rows.length}`
  )
}

Start with a batch size of 5. Increase if your plan's rate limits allow it.

Error handlingError Handling

Real CSV data has issues. Some rows will have missing URLs, empty fields, or encoding problems. Add basic error handling:

try {
  const response = await fetch(/* ... */);
  if (!response.ok) {
    console.error(`Failed row ${index}: ${response.status}`);
    continue;
  }
  // save image...
} catch (err) {
  console.error(`Error on row ${index}: ${err.message}`);
  continue;
}

Log failures but don't let one bad row stop the entire batch.

Common csv pitfallsCommon CSV Pitfalls

Commas in data. If your product names contain commas ("Running Shoe, Men's"), wrap them in quotes in the CSV or use a tab-separated format instead.

Image URLs with spaces. URL-encode spaces as %20. Some CSV exports from e-commerce platforms include unencoded spaces in URLs.

Excel encoding. Excel sometimes saves CSV with BOM (byte order mark) or Windows line endings. If you're getting parse errors, re-save as UTF-8 without BOM.

Missing headers. The first row of your CSV must be column headers. If it's not, the script won't know which column maps to which template field. I've debugged this one more times than I'd like to admit.

Cost breakdownCost Breakdown

VolumeImejis.io PlanMonthly CostPer Image
100Free$0$0.00
1,000Basic$14.99$0.015
10,000Pro$24.99$0.0025
100,000Unlimited$69.99$0.0007

At the Pro level, generating 5,000 product images from a CSV costs about $12.50 worth of API calls. Compare that to a designer spending 3-5 minutes per image in Canva. At 5,000 images, that's 250-400 hours of design time.

Getting startedGetting Started

  1. Sign up for Imejis.io — 100 free images per month
  2. Design a template with clearly named layers
  3. Prepare a test CSV with 5-10 rows
  4. Run the script (or set up the Zapier workflow)
  5. Check the output for any layout issues
  6. Process your full dataset once the template is validated

For the JSON data format details, see our Generate Images from JSON guide. For pricing across all providers, check our Image Generation API Pricing Comparison. And for e-commerce specifically, see Dynamic Product Images with Live Pricing.

FaqFAQ

Can i generate images from a csv fileCan I generate images from a CSV file?

Yes. Read each row, call an image API like Imejis.io with the row data, and save the result. Each row becomes one image with the correct data from your spreadsheet.

How long does it take to generate 1000 images from a csvHow long does it take to generate 1,000 images from a CSV?

About 33 minutes sequentially, or 7 minutes with 5 parallel requests. Each image generates in under 2 seconds. Imejis.io Pro ($24.99/month) covers 10,000 images.

Can i do this without codingCan I do this without coding?

Yes. Upload your CSV to Google Sheets or Airtable, then use Zapier or Make to loop through rows and call the API. Setup takes about an hour. You can also share designs with public links for a completely code-free option.

What csv columns do i needWhat CSV columns do I need?

Columns matching your template's dynamic fields. If the template has headline, price, and product_image layers, your CSV needs columns with those names and data for each row.

How much does bulk image generation costHow much does bulk image generation cost?

Imejis.io's free tier covers 100/month. Pro ($24.99) covers 10,000 at $0.0025 per image. That's a fraction of the cost of manual design.

Stop designing one image at a timeStop Designing One Image at a Time

Your data is in a spreadsheet. Your template is ready. The script is 20 lines of code. Try Imejis.io free and batch-generate your first 100 images today.