Uploading assets
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.
Use-cases
These are some examples of apps that can benefit from uploading assets:
- Stock photo libraries, such as Pixabay
- Digital asset management tools, such as Brandfolder
- Generative AI apps, such as Text to Image
The user experience
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.
Supported asset types
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.
Audio
Apps can upload the following types of audio files:
The maximum size of an audio file is 50MB.
Images
Apps can upload the following types of image files:
The maximum size of an image file is 50MB, except for SVGs, which are limited to 3MB.
Videos
Apps can upload the following types of video files:
The maximum size of a video file is 100MB.
How to upload assets
Step 1: Enable the required permissions
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.
Step 2: Start the upload
Import the upload
method from the @canva/asset
package:
import { upload } from "@canva/asset";
When calling the method, the expected properties depend on the type of asset being uploaded:
- Audio
- Images
- Videos
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",});
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 anaudio/mp3
file, butaudio/wav
will not work.
If the method call is successful, it returns a reference:
console.log("The reference for the upload is:", result.ref);
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.
(Optional) Step 3: Check when the upload is complete
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.");
(Optional) Step 4: Add the asset to the user's design
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:
SVG limitations
This section describes the limitations that apps must consider when uploading SVGs.
File size
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.
Download timeouts
The SVG image should be downloadable from the server within 5 seconds.
Elements
Some SVG elements (tags) are not allowed and an upload will fail if the elements are present.
Animation elements
animate
animatemotion
animatetransform
discard
mpath
set
Deprecated elements
altglyph
altglyphdef
altglyphitem
cursor
glyph
glyphref
missing-glyph
tref
Font elements
font
font-face
font-face-format
font-face-name
font-face-src
font-face-uri
Unsafe elements
a
foreignobject
script
switch
Attributes
Some attributes are either not allowed in SVG files or have certain restrictions.
Blocked attributes
crossorigin
lang
media
onload
ping
referrerpolicy
rel
rendering-intent
requiredextensions
requiredfeatures
systemlanguage
tabindex
transform-origin
unicode
vector-effect
Restricted attributes
- The
href
attribute of animage
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 themix-blend-mode
property.
Additional considerations
- All assets must comply with Canva's Acceptable Use Policy.
- All assets must comply with Canva's Upload formats and requirements.
API reference
Code samples
Uploading audio
import React from "react";import { upload } from "@canva/asset";export function App() {async function handleClick() {// Start uploading the mediaconst 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 uploadconsole.log("The reference for the upload is:", result.ref);// Wait for the upload to completeawait result.whenUploaded();console.log("The upload is complete.");}return (<div><button onClick={handleClick}>Upload audio</button></div>);}
Uploading images
import React from "react";import { upload } from "@canva/asset";export function App() {async function handleClick() {// Start uploading the mediaconst 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 uploadconsole.log("The reference for the upload is:", result.ref);// Wait for the upload to completeawait result.whenUploaded();console.log("The upload is complete.");}return (<div><button onClick={handleClick}>Upload image</button></div>);}
Uploading videos
import React from "react";import { upload } from "@canva/asset";export function App() {async function handleClick() {// Start uploading the mediaconst 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 uploadconsole.log("The reference for the upload is:", result.ref);// Wait for the upload to completeawait result.whenUploaded();console.log("The upload is complete.");}return (<div><button onClick={handleClick}>Upload video</button></div>);}