Making Canva REST API requests from the CLI
canva api calls Canva's REST APIs using your Canva CLI login. Commands are grouped by the resource they act on, such as canva api designs create, and --help works at every level to show the available groups, commands, and flags.
This page explains how to find a command, pass input to it, and read the JSON response. The examples later on the page are optional starting points. You don't need to run them to use canva api.
Choose the approach that matches what you're doing:
- Work with your own designs by chatting with an AI assistant: Set up the Canva AI Connector(opens in a new tab or window).
- Build a product that acts on your users' Canva accounts: See Quickstart.
- Interact with Canva from a terminal, a script, or a coding agent, using files on your machine: Use
canva api.
Before you begin
You need:
- Node.js
v24 - npm
v11 - A Canva(opens in a new tab or window) account
- The Canva CLI. For install steps, see Canva CLI.
Commands act as the account you're logged in to the CLI with, so run canva login if you aren't logged in.
Earlier versions of the CLI didn't ask for the access that canva api needs, so if a call fails with a missing_scope error, log in again to grant it.
Find a command
Every supported REST API operation is a command like this:
canva api <group> <command>
Groups collect related operations, such as designs or exports. You don't need to memorize the tree. Print it with --help:
canva api --helpcanva api designs --helpcanva api designs create --help
Commands are named after the REST API operation rather than its URL path. For example, the Get design operation, GET /v1/designs/{designId}, is canva api designs get.
IDs such as a design ID can be a positional argument or a kebab-case flag. These two commands call the same operation:
canva api designs get DAF123abccanva api designs get --design-id DAF123abc
Confirm a command's flags with --help instead of guessing them. If a call asks you to log in, run canva login and try the call again.
Pass input to a command
You can pass input with operation flags (recommended) or with --body (advanced). Use flags when --help lists them. Use --body when flags can't express a nested payload, such as JSON copied from the REST API reference.
Pass input with flags (recommended)
Run canva api <group> <command> --help to see the flags for that operation. For example, this command creates a presentation:
canva api designs create --preset presentation --title "Q3 Review"
Pass a JSON body (advanced)
--body is only available on operations that send a JSON request body. Commands that only read data, such as designs get, don't accept it.
canva api designs create --body @payload.json
Check a command before you send it
Add --dry-run to see what a command resolves to without calling the REST API. This is useful before a command that creates or changes something.
canva api designs create --preset presentation --title "Q3 Review" --dry-run
Understand the JSON response
When a call reaches the REST API, or when it fails after the CLI accepts your arguments, the CLI prints one JSON object to stdout and nothing else. You can pipe that object into jq or a script.
If you omit a required argument or pass an unknown flag, the CLI prints a usage message to standard error instead of JSON.
A successful response looks like this:
{"ok": true,"data": {"design": {"id": "DAF123abc"}},"next": [],"meta": {"status": 200,"durationMs": 12}}
A failed call looks like this:
{"ok": false,"error": {"code": "NOT_FOUND","message": "Design not found."},"next": [],"meta": {"status": 404,"durationMs": 18}}
The object has these fields:
ok:truewhen the call succeeded,falsewhen it failed.data: The REST API response body, unwrapped, so the API reference still applies. On failure,erroroccupies this slot instead, withcode,message, and an optionalupstreamErrorCode.next: Suggested follow-up commands, such ascanva loginif you need to sign in. You can ignore these hints.meta.status: The HTTP status from the API. It's0when the CLI didn't call the API, for example if you aren't logged in, the input is invalid, or you pass--dry-run.meta.durationMs: How long the call took, in milliseconds.
For example, to extract the link for editing a design:
canva api designs get DAF123abc | jq -r .data.design.urls.edit_url
Examples
The following commands are optional examples, not required steps. Replace the IDs with values from your own account, and run --help on each command to confirm its flags.
Look up a design
canva api designs get DAF123abc
List your designs
canva api designs list
List the items in a folder
For the folder IDs you can use and the shape of each item, see List folder items.
canva api folders list-items --folder-id root
A continuation value in the response means the folder holds more items than one response returns. Pass it back to get the next page, and repeat until a response has no continuation:
canva api folders list-items --folder-id root --continuation "RkFGMgXlsVTDbMd:MR3L0QjiaUzycIAjx0yMyuNiV0O"
Create a design
canva api designs create --preset presentation --title "Q3 Review"
The data field of the response includes the URLs for editing and viewing the design, and an ID you can pass to other commands:
{"design": {"id": "DAFVztcvd9z","title": "Q3 Review","urls": {"edit_url": "https://www.canva.com/api/design/eyJhbGciOiJkaXIiLCJlbmMi/edit","view_url": "https://www.canva.com/api/design/eyJhbGciOiJkaXIiLCJlbmMi/view"}}}
Upload a file from your machine
This example adds a local file to your Canva content library, which gives you an asset ID you can use in other calls. For the supported file types, see Assets.
Uploading creates an asynchronous job. You start the job, then poll it until the job finishes. The CLI doesn't wait for the job.
Run canva api asset-uploads create --help to confirm how to pass the file path and the asset name.
-
Start the job with a call to
canva api asset-uploads create.canva api asset-uploads create --file ./cover-photo.jpg --name "Q3 cover photo"SHELL -
The command returns an upload job with its ID and status in
data.{"job": {"id": "e08861ae-3b29-45db-8dc1-1fe0bf7f1cc8","status": "in_progress"}}JSONSave the job ID so you can check the job's status.
-
With the job ID from the previous step, use
canva api asset-uploads getto poll the job untildata.job.statuschanges fromin_progressto eithersuccessorfailed. For how often to call it, see Job polling strategies.canva api asset-uploads get e08861ae-3b29-45db-8dc1-1fe0bf7f1cc8SHELL -
A successfully completed job includes the new asset.
{"job": {"id": "e08861ae-3b29-45db-8dc1-1fe0bf7f1cc8","status": "success","asset": {"id": "Msd59349ff","type": "image","name": "Q3 cover photo"}}}JSONUse
data.job.asset.idwherever a call takes an asset ID. Afailedjob has noasset, and instead has anerrorwith the reason, such as a file that's too big. For details, see Create asset upload job.