Uploading assets

How to upload assets to a user's media library.

Apps can upload assets, such as images or videos, to Canva's backend. The user can access these assets in the Canva editor, via the Uploads tab, and the app can add the assets to the user's design.

These are some examples of apps that can benefit from uploading assets:

When an app starts uploading an asset, the user can see the upload progress in the Uploads tab, and the asset's thumbnail is overlaid with a progress indicator. A toast notification appears when the upload is complete.

Upload an asset only with the user's explicit permission and intent, such as when the user clicks a button. It's better to show users a preview of the object to upload first, and then confirm with the user whether to proceed with the upload.

The asset counts against the user's storage quota. If the user has a Canva Pro account, their storage quota is 1TB. Otherwise, their storage quota is 5GB.

The uploaded asset is only available to the user who uploaded it.

Apps can upload the following types of assets to a user's media library:

  • Audio
  • Images
  • Videos

There are limitations that apply to each type of assets, such as supported file formats and sizes.

Apps can upload the following types of audio files:

NameMIME typeCommon file extensions
MPEGaudio/mpeg.mpg, .mpeg, .mp1, .mp2, .mp3
MP4 Audioaudio/mp4.mp4, .m4a
M4Aaudio/x-m4a.m4a
MP3audio/mp3.mp3
OGGaudio/ogg.ogg, .oga
WAVaudio/wav.wav
X-WAVaudio/x-wav.wav
WEBMaudio/webm.webm

The maximum size of an audio file is 50MB.

Apps can upload the following types of image files:

NameMIME typeCommon file extensions
HEICimage/heic.heic
JPEGimage/jpeg.jpg, .jpeg
PNGimage/png.png
SVGimage/svg+xml.svg
TIFFimage/tiff.tiff, .tif
WebPimage/webp.webp

The maximum size of an image file is 50MB, except for SVGs, which are limited to 3MB.

Apps can upload the following types of video files:

NameMIME typeCommon file extensions
AVIvideo/avi.avi
GIFimage/gif.gif
M4Vvideo/x-m4v.m4v
Matroskavideo/x-matroska.mkv
QuickTimevideo/quicktime.mov
MP4video/mp4.mp4
MPEGvideo/mpeg.mpg, .mpeg
WebMvideo/webm.webm

The maximum size of a video file is 100MB.

To allow the app to upload assets, enable the canva:asset:private:write permission via the Developer Portal. In the future, the Apps SDK will throw an error if the required permissions are not enabled.

To learn more, see Configuring permissions.

Import the upload method from the @canva/asset package:

import { upload } from "@canva/asset";
ts

When calling the method, the expected properties depend on the type of asset being uploaded:

The following snippet demonstrates the required properties for uploading audio assets:

const result = await upload({
type: "audio",
title: "Example audio",
mimeType: "audio/mp3",
url: "https://www.canva.dev/example-assets/audio-import/audio.mp3",
});
ts

In all cases:

  • The URLs must be exposed via the internet and available to Canva's backend. This means localhost URLs won't work.
  • For images and video, the MIME type must match the format of the uploaded asset. However, for audio, inexact MIME types are allowed for assets that belong to the same format. For example, you can use audio/mpeg for an audio/mp3 file, but audio/wav will not work.

If the method call is successful, it returns a reference:

console.log("The reference for the upload is:", result.ref);
ts

A reference is a unique identifier that points to an asset in Canva's backend. This reference lets an app interact with an asset before it has finished uploading.

The upload method can return an optional whenUploaded method that informs the user that their upload is complete and returns a Promise. By waiting for the Promise to resolve, the app can determine when an asset has finished uploading:

await result.whenUploaded();
console.log("The upload is complete.");
ts

By default, uploading an asset only makes it available to a user via their Uploads tab. It doesn't add the asset to the user's design. To learn how to add assets to a design, see:

This section describes the limitations that apps must consider when uploading SVGs.

For most users, the maximum file size for SVGs is 3MB. If a user is a contributor, the maximum file size for SVGs is 10MB.

The SVG image should be downloadable from the server within 5 seconds.

Some SVG elements (tags) are not allowed and an upload will fail if the elements are present.

  • animate
  • animatemotion
  • animatetransform
  • discard
  • mpath
  • set
  • altglyph
  • altglyphdef
  • altglyphitem
  • cursor
  • glyph
  • glyphref
  • missing-glyph
  • tref
  • font
  • font-face
  • font-face-format
  • font-face-name
  • font-face-src
  • font-face-uri
  • a
  • foreignobject
  • script
  • switch

Some attributes are either not allowed in SVG files or have certain restrictions.

  • crossorigin
  • lang
  • media
  • onload
  • ping
  • referrerpolicy
  • rel
  • rendering-intent
  • requiredextensions
  • requiredfeatures
  • systemlanguage
  • tabindex
  • transform-origin
  • unicode
  • vector-effect
  • The href attribute of an image element only supports data URLs for PNG and JPEG images. Other image formats, such as SVGs, are not supported as data URLs.
  • The URL in a href attribute must not point to a location that exists outside of the SVG.
  • The style attribute must not use the mix-blend-mode property.
import React from "react";
import { upload } from "@canva/asset";
export function App() {
async function handleClick() {
// Start uploading the media
const result = await upload({
type: "audio",
title: "Example audio",
mimeType: "audio/mp3",
url: "https://www.canva.dev/example-assets/audio-import/audio.mp3",
});
// Get the reference for the upload
console.log("The reference for the upload is:", result.ref);
// Wait for the upload to complete
await result.whenUploaded();
console.log("The upload is complete.");
}
return (
<div>
<button onClick={handleClick}>Upload audio</button>
</div>
);
}
tsx
import React from "react";
import { upload } from "@canva/asset";
export function App() {
async function handleClick() {
// Start uploading the media
const result = await upload({
type: "image",
mimeType: "image/jpeg",
url: "https://www.canva.dev/example-assets/image-import/image.jpg",
thumbnailUrl:
"https://www.canva.dev/example-assets/image-import/thumbnail.jpg",
});
// Get the reference for the upload
console.log("The reference for the upload is:", result.ref);
// Wait for the upload to complete
await result.whenUploaded();
console.log("The upload is complete.");
}
return (
<div>
<button onClick={handleClick}>Upload image</button>
</div>
);
}
tsx
import React from "react";
import { upload } from "@canva/asset";
export function App() {
async function handleClick() {
// Start uploading the media
const result = await upload({
type: "video",
mimeType: "video/mp4",
url: "https://www.canva.dev/example-assets/video-import/video.mp4",
thumbnailImageUrl:
"https://www.canva.dev/example-assets/video-import/thumbnail-image.jpg",
thumbnailVideoUrl:
"https://www.canva.dev/example-assets/video-import/thumbnail-video.mp4",
});
// Get the reference for the upload
console.log("The reference for the upload is:", result.ref);
// Wait for the upload to complete
await result.whenUploaded();
console.log("The upload is complete.");
}
return (
<div>
<button onClick={handleClick}>Upload video</button>
</div>
);
}
tsx