Quick start

Create a content extension in under 30 minutes.

A content extension imports content, such as photos and illustrations, into Canva. Users can access this content via the side panel and add it to their designs.

This quick start guide demonstrates how to create a content extension that imports content from Lorem Picsum, an API for placeholder photos.

This guide assumes experience with:

  • Node.js
  • Express.js

At its most basic, a content extension is an API that receives requests from Canva and responds with data in a format that Canva understands. Canva expects this API to have certain paths to handle different requests.

To get an API up and running as quickly as possible, we recommend using Glitch, a web-based editor for creating and deploying Node.js apps. Glitch is free and registration is not required.

To set up a project with Glitch:

  1. Click the following button:

    Remix on Glitch

    This opens the Glitch editor with the source code of a simple content extension.

  2. Click Share.

  3. Copy the URL from the Live site field. You need this URL for a later step.

  1. Log in to the Developer Portal.
  2. Navigate to Your integrations.
  3. Click Create an app.
  4. Choose a target audience for the app. (The default option is Everyone.)
  5. Click Next.
  6. Select Create content.
  7. Click Next.
  8. Click Create app.
  1. Paste the Live site URL from Glitch into the Base URL field.
  2. For the Layout option, select Grid.
  3. For the Content type option, select Images.

For guidelines on choosing the layout that's most appropriate for your content type, see Choose the best layout.

To learn about the supported content types, see Content types. For additional requirements that apply to each content type, see Choose the best content types.

  1. Click Preview.
  2. Select the extension from the dropdown list.
  3. Click Use.

When the extension loads, Canva sends a POST request to the following endpoint:


This endpoint responds with an array of images, which Canva renders in the side panel.

This guide has only scratched the surface of what's possible with content extensions.

To learn more, refer to the following guides:

You can also create a support ticket if you need additional help.

To provide users the best experience with content extensions, see UX guidelines for content extensions.

const axios = require("axios");
const express = require("express");
const app = express();
app.post("/content/resources/find", async (request, response) => {
// Get a list of images
const { data } = await axios.get("https://picsum.photos/v2/list");
// Create an array of resources
const resources = data.map((resource) => {
return {
type: "IMAGE",
id: resource.id, // This ID should always refer to the same piece of media
name: resource.author || resource.id,
thumbnail: {
url: resource.download_url,
url: resource.download_url,
contentType: "image/jpeg",
// Respond with the resources
type: "SUCCESS",
app.listen(process.env.PORT || 3000);