Publish extensions

What are publish extensions? Why create one?

A publish extension adds a publish destination to Canva. This destination appears in the Publish menu. Users can then publish their designs to the destination platform.

To create a publish extension from scratch, check out the Quick start guide.

Examples of publish extensions

These are some examples of apps with publish extensions:

  • Pinterest - Post designs to your boards on Pinterest.

  • Slack - Share designs to your channels on Slack.

  • Twitter - Post designs on Twitter.

You can find more examples at

Supported publish formats

A publish extension can publish the user's design in any of the following formats:

  • JPG

  • PNG

  • PDF

  • PPTX

You can configure the supported formats via the Developer Portal.

How users experience publish extensions

Users can find publish extensions via the Publish menu.

When a user opens a publish extension, the user experience depends on the layout of the extension, which you can configure via the Developer Portal. This is an example of the user experience of an extension that uses the Basic layout:

When a user clicks the Save button, Canva sends a request to the destination platform to upload the user's design. The extension then responds with a URL where the user can view their design on the destination platform.

With additional configuration, a publish extension can also:

How publish extensions work

At its most basic, a publish extension is a REST API.

Canva expects this API to have the following endpoints:

As a user interacts with a publish extension via Canva's UI, Canva sends requests to these endpoints and expects to receive responses in a format that it understands.

The /publish/resources/find and /publish/resources/get endpoints are only required for extensions that use the Flat list or Nested list layout.

Request-response cycle

The request-response cycle of a publish extension depends on the extension's layout. This is the request-response cycle of a publish extension that uses the Basic layout:

Canva sends additional requests if the extension supports authentication.


const express = require("express");
const jimp = require("jimp");
const path = require("path");
const url = require("url");
const app = express();
app.use(express.static("public"));"/publish/resources/upload", async (request, response) => {
// Download the image
const [asset] = request.body.assets;
const image = await;
// Write the file to disk
const filePath = path.join(__dirname, "public",;
await image.writeAsync(filePath);
// Respond to the request
type: "SUCCESS",
url: url.format({
protocol: request.protocol,
host: request.get("host"),
app.listen(process.env.PORT || 3000);