Generate images with CRAFT
The image generation APIs are currently provided as a preview. Be aware of the following:
- There might be unannounced breaking changes.
- Any breaking changes to preview APIs won't produce a new API version.
- Public apps that use preview APIs will not pass the review process, and can't be made available to all Canva users.
Use CRAFT-1 2K (craft_v1_2k), Canva's first-party image generation model, to generate an image from your own platform. This guide shows you how to create an app, start a generation job, and download the image.
Set up your app
Image generation works with a public or private app, or with a service app. Choose one of the following:
- Public or private app: The app acts on behalf of a Canva user, who signs in and authorizes it. The access token needs the
asset:writescope, and the user needs theimage_generationcapability. Starting a job uses that user's AI credit allowance(opens in a new tab or window). If the user has reached their allowance, the request returns a402error with thecredit_quota_exceededcode. - Service app: The app acts on its own behalf, using the OAuth client credentials flow. The access token needs the
service:asset:writescope. Capabilities don't apply to a service app. Starting a job uses credits from your team's API credit pool. CRAFT-1 2K costs 3 credits per 2K image. For the rates, and for how a failed job returns credits, see Canva REST API credit rates. If the app has reached its credit quota, the request returns a402error with theapp_credit_quota_exceededcode.
You can download the generated image from a URL. A public or private app can also save the image to the user's Canva account.
Public or private app
To set up a public or private app:
- Create an app and enable the REST APIs using the Quickstart for public or private apps.
- In the Developer Portal, go to Outside Canva > Configuration. Under Scopes, select Write for asset. This grants the
asset:writescope. - Authorize the user with the authorization code flow. You can check the
image_generationcapability with Get user capabilities.
Service app
To set up a service app:
- Create a service app and buy an API pack using the Quickstart for service apps.
- In the Developer Portal, go to Outside Canva > Configuration. Under Scopes, select Write for
service:asset. This grants theservice:asset:writescope. - Generate an access token that includes
service:asset:write, using the client credentials flow.
Generate an image
From your backend, call Create image generation job. Set model to craft_v1_2k so the job uses CRAFT-1 2K. If you omit model, Canva selects the model for the request.
Replace {access token} with your access token, and {idempotency key} with a new UUID for this attempt. Reuse that UUID when you retry the same request. A repeated key returns the original job for 24 hours, including when that job failed. To start a new attempt, use a new UUID.
curl --request POST 'https://api.canva.com/rest/v1/image-generations' \--header 'Authorization: Bearer {access token}' \--header 'Content-Type: application/json' \--data '{"prompt": "A ceramic coffee cup on a sunlit table, soft natural light","model": "craft_v1_2k","idempotency_key": "{idempotency key}"}'
The response includes job.id. Copy it for the next step.
To also save the image in the user's Canva account, add "asset_upload": { "type": "upload" } to the request body. This requires a public or private app. The job then stays in_progress until the asset has finished importing, and a successful result includes job.result.image.asset as well as the download URL.
Get the generated image
Call Get image generation job with the same access token that created the job. Generation is asynchronous, so request the job again while job.status is in_progress. For the workflow and how often to poll, see Asynchronous job endpoints.
curl --request GET 'https://api.canva.com/rest/v1/image-generations/{jobId}' \--header 'Authorization: Bearer {access token}'
Replace {jobId} with job.id from the create response.
When job.status is success, download the image from job.result.image.url. The URL is valid for 24 hours. When job.status is failed, read job.error.code and job.error.message. For model_not_available and model_retired, see Generations.
The prompt in this guide generates an image like the following:

Call CRAFT from the Canva CLI
You can run the same requests from a terminal with the Canva CLI. The CLI calls the REST APIs as the Canva account you're logged in with, so that account needs the image_generation capability. Run canva login first. If a call fails with MISSING_SCOPE, log in again so the CLI can request asset:write.
canva api generations create-image \--model craft_v1_2k \--prompt "A ceramic coffee cup on a sunlit table, soft natural light" \--idempotency-key "{idempotency key}"
The CLI prints a JSON object. The job ID is data.job.id.
canva api generations get-image --job-id "{job ID}"
Check data.job.status the same way as the REST response. On success, the download URL is data.job.result.image.url.
Next steps
For more detail:
- Read the request and response fields for Create image generation job and Get image generation job.
- Compare CRAFT-1 2K with the other image models on Generations.
- See how many credits a service app uses on Canva REST API credit rates.