Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Bulk-create Canva designs from tabular data using a brand template with autofill fields, producing one design per row. Use when users say \"bulk create designs from this CSV\", \"generate one design per row\", \"create a design for each product\", \"batch generate from a template\", or \"autofill a template from a spreadsheet\". Accepts any tabular data source — uploaded files, pasted tables, JSON
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-07 | ✗→✓ | ▲ Improved | 25% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 67% | 0% |
| case-03 | ✗→✓ | ▲ Improved | -33% | 0% |
| case-04 | ✗→✓ | ▲ Improved | 73% | 0% |
| case-10 | ✗→✓ | ▲ Improved | 38% | 0% |
Create one Canva design per row of data by autofilling a brand template with data tags.
Accept data in any form the user provides and extract a list of rows with named columns:
If no data has been provided, ask the user to share it in whatever format is convenient for them.
Once parsed, show the user:
If the user hasn't specified a template, search for autofill-capable ones:
Canva:search-brand-templates dataset=non_emptyShow the results and ask the user to pick one. If they already named or described a template, search with that query.
Canva:get-brand-template-dataset template_id=<selected_id>This returns the field names and types (text, image, chart) that the template expects.
Present a mapping table to the user:
| Template Field | Type | Matched CSV Column | Notes | |---|---|---|---| | product_name | text | Product Name | auto-matched | | price | text | Price | auto-matched | | hero_image | image | (none) | no match — image fields need asset IDs |
Matching rules:
Confirm the mapping with the user before proceeding, especially if there are unmapped fields or ambiguous matches.
There are two ways a CSV can supply images for image-type template fields:
Pattern A — CSV has a Canva asset ID column (e.g. image_asset_id): Use the asset ID value directly in the autofill-design call:
json{ "image": { "type": "image", "asset_id": "<value from CSV column>" } }
Pattern B — CSV has an image URL column (e.g. image_url): URLs cannot be passed directly to autofill-design. Upload each URL to Canva first using Canva:upload-asset-from-url, capture the returned asset ID, then use it in the autofill call. Do the upload immediately before creating that row's design so failures stay localised.
Pattern C — No image column in CSV: Ask the user whether to skip the image field (template default image stays) or abort. Skipping is safe — just omit the image key from the data payload entirely.
Loop through every CSV row and call Canva:autofill-design for each one. Call them sequentially, not all at once — the API may have rate limits and sequential calls are easier to debug.
For each row:
Canva:upload-asset-from-url to get a Canva asset ID.data payload from the confirmed field mapping:json{ "text_field_name": { "type": "text", "text": "<value from CSV>" }, "image_field_name": { "type": "image", "asset_id": "<asset ID>" } }
Canva:autofill-design with the template ID, data payload, and a descriptive title using the row number or a meaningful column value (e.g. "Bulk Design - Row 3 - <identifier>").Track results as you go:
Row 1 / 50: Created — <design_url>
Row 2 / 50: Created — <design_url>
Row 3 / 50: Failed — <error>After all rows are processed, summarise:
Offer to save a summary CSV with columns: row, status, design_url, error.
get-brand-template-dataset.Other measured skills in the registry, with their headline benchmark lift.