SKILL.md
Canva Core Workflow A — Design Creation & Export
Overview
The primary Canva integration workflow: create designs via the REST API, let users edit them in Canva's editor, then export finished designs as PDF/PNG/JPG for downstream use (email campaigns, social posts, print orders).
Prerequisites
- Completed
canva-install-authsetup with valid access token - Scopes:
design:content:write,design:content:read,design:meta:read
Instructions
Step 1: Create a Design
// POST https://api.canva.com/rest/v1/designs
// Rate limit: 20 req/min per user
// Scope: design:content:write
interface CreateDesignRequest {
design_type:
| { type: 'preset'; name: 'doc' | 'whiteboard' | 'presentation' }
| { type: 'custom'; width: number; height: number }; // 40-8000 px
title?: string; // 1-255 characters
asset_id?: string; // Image asset to insert
}
// Create a social media post (custom dimensions)
const { design } = await canvaAPI('/designs', token, {
method: 'POST',
body: JSON.stringify({
design_type: { type: 'custom', width: 1080, height: 1080 },
title: 'Instagram Post — Q1 Campaign',
}),
});
// design.id — unique identifier for all future operations
// design.urls.edit_url — redirect user here to edit (expires 30 days)
// design.urls.view_url — read-only link (expires 30 days)
// design.thumbnail.url — preview image (expires 15 minutes)
Note: Blank designs are auto-deleted after 7 days if never edited.
Step 2: Redirect User to Edit
// Redirect the user to Canva's editor
// The edit_url is user-specific and expires after 30 days
res.redirect(design.urls.edit_url);
Step 3: Get Design Metadata
// GET https://api.canva.com/rest/v1/designs/{designId}
// Rate limit: 100 req/min per user
// Scope: design:meta:read
const { design: meta } = await canvaAPI(`/designs/${designId}`, token);
console.log(`Title: ${meta.title}`);
console.log(`Pages: ${meta.page_count}`);
console.log(`Created: ${new Date(meta.created_at * 1000).toISOString()}`);
console.log(`Updated: ${new Date(meta.updated_at * 1000).toISOString()}`);
console.log(`Owner: user=${meta.owner.user_id}, team=${meta.owner.team_id}`);
