Get design analytics viewers

Get information about users who have viewed a design.

This API is 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 integrations that use preview APIs will not pass the review process, and can't be made available to all Canva users.

To use this API, your integration must act on behalf of a user who is a member of a Canva Enterprise(opens in a new tab or window) organization.

Lists viewers for a design, ordered by most recent view first.

HTTP method and URL path

GET https://api.canva.com/rest/v1/designs/{designId}/analytics/viewers

This operation is rate limited to 100 requests per minute for each user of your integration.

Authentication and authorization

This endpoint requires a valid access token that acts on behalf of a user.

Scopes

The access token must have all the following scopes (permissions):

  • design:content:read

Capabilities

The user must have at least one of the following capabilities:

  • analytics

Header parameters

Authorizationstring
Required

Provides credentials to authenticate the request, in the form of a Bearer token.

For example: Authorization: Bearer {token}

Path parameters

designIdstring
Required

The design ID.

Query parameters

link_idstring
Optional

Filters viewers by a specific trackable link. If omitted, only viewers who visited the design without using a trackable link are returned.

first_viewed_afterinteger
Optional

Only returns viewers whose first view happened after this time, as a Unix timestamp (in seconds since the Unix Epoch).

limitinteger
Optional

The maximum number of viewers to return per page.

Minimum: 1

Maximum: 100

Default value: 50

continuationstring
Optional

If the success response contains a continuation token, there are more viewers you can list. You can use this token as a query parameter and retrieve more viewers from the list, for example /v1/designs/{designId}/analytics/viewers?continuation={continuation}.

To retrieve all viewers, you might need to make multiple requests.

Example request

Examples for using the /v1/designs/{designId}/analytics/viewers endpoint:

curl --request GET 'https://api.canva.com/rest/v1/designs/{designId}/analytics/viewers' \
--header 'Authorization: Bearer {token}'
SH
const fetch = require("node-fetch");
fetch("https://api.canva.com/rest/v1/designs/{designId}/analytics/viewers", {
method: "GET",
headers: {
"Authorization": "Bearer {token}",
},
})
.then(async (response) => {
const data = await response.json();
console.log(data);
})
.catch(err => console.error(err));
JS
import java.io.IOException;
import java.net.URI;
import java.net.http.*;
public class ApiExample {
public static void main(String[] args) throws IOException, InterruptedException {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.canva.com/rest/v1/designs/{designId}/analytics/viewers"))
.header("Authorization", "Bearer {token}")
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> response = HttpClient.newHttpClient().send(
request,
HttpResponse.BodyHandlers.ofString()
);
System.out.println(response.body());
}
}
JAVA
import requests
headers = {
"Authorization": "Bearer {token}"
}
response = requests.get("https://api.canva.com/rest/v1/designs/{designId}/analytics/viewers",
headers=headers
)
print(response.json())
PY
using System.Net.Http;
var client = new HttpClient();
var request = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri("https://api.canva.com/rest/v1/designs/{designId}/analytics/viewers"),
Headers =
{
{ "Authorization", "Bearer {token}" },
},
};
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
};
CSHARP
package main
import (
"fmt"
"io"
"net/http"
)
func main() {
url := "https://api.canva.com/rest/v1/designs/{designId}/analytics/viewers"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer {token}")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}
GO
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://api.canva.com/rest/v1/designs/{designId}/analytics/viewers",
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => array(
'Authorization: Bearer {token}',
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if (empty($err)) {
echo $response;
} else {
echo "Error: " . $err;
}
PHP
require 'net/http'
require 'uri'
url = URI('https://api.canva.com/rest/v1/designs/{designId}/analytics/viewers')
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request['Authorization'] = 'Bearer {token}'
response = http.request(request)
puts response.read_body
RUBY

Success response

If successful, the endpoint returns a 200 response with a JSON body with the following parameters:

itemsViewer[]

The list of viewers.

viewer_idstring

An opaque identifier for the viewer. Use this value when filtering page view results by viewer.

last_viewed_atinteger

When the viewer most recently opened the design, as a Unix timestamp (in seconds since the Unix Epoch).

viewer_typestring

How the viewer accessed the design.

Available values:

  • editor: The viewer accessed the design with edit access.
  • commenter: The viewer accessed the design with comment access.
  • viewer: The viewer accessed the design with view-only access.
visibilitystring

How this viewer should be presented to the caller.

Available values:

  • shown: The viewer's identity is visible, and their user details are included.
  • anonymous: The viewer is anonymous, so their identity is not available.
  • opt_out: The viewer has opted out of design analytics, but some data was already collected for this viewer previosly.
  • another_team: The viewer belongs to a different team, so their identity is not shared.
  • deleted: The viewer's account has been deleted.
userobject
Optional

The user details of the viewer. This is omitted for viewers whose identity is not visible.

user_idstring
Optional

The ID of the user.

team_idstring
Optional

The ID of the user's Canva Team.

display_namestring
Optional

The name of the user as shown in the Canva UI.

total_view_duration_secondsinteger
Optional

The total time this viewer has spent viewing the design, in seconds.

first_viewed_atinteger
Optional

When the viewer first viewed the design, as a Unix timestamp (in seconds since the Unix Epoch).

pages_viewedinteger
Optional

The number of pages this viewer viewed for more than one second.

form_factorstring
Optional

The device form factor used to view the design.

Available values:

  • small: A small device, such as a phone.
  • large: A large device, such as a laptop, desktop, or large tablet.
device_operating_systemstring
Optional

The simplified operating system name for the viewer's device.

city_countrystring
Optional

The viewer location as city and country. This is only returned for anonymous viewers.

total_view_countinteger
Optional

The number of times this viewer opened the design.

continuationstring
Optional

If the success response contains a continuation token, there are more viewers you can list. You can use this token as a query parameter and retrieve more viewers from the list, for example /v1/designs/{designId}/analytics/viewers?continuation={continuation}.

To retrieve all viewers, you might need to make multiple requests.

Example response

{
"items": [
{
"viewer_id": "b2d44753-f996-46ff-8f01-d4143911550f",
"user": {},
"last_viewed_at": 1748044800,
"viewer_type": "editor",
"visibility": "shown",
"total_view_duration_seconds": 312,
"first_viewed_at": 1745452800,
"pages_viewed": 8,
"form_factor": "small",
"device_operating_system": "macOS",
"city_country": "Sydney, Australia",
"total_view_count": 14
}
],
"continuation": "RkFGMgXlsVTDbMd:MR3L0QjiaUzycIAjx0yMyuNiV0OildoiOwL0x32G4NjNu4FwtAQNxowUQNMMYN"
}
JSON

Error responses

400 Bad Request

codestring

A short string indicating what failed. This field can be used to handle errors programmatically. For a complete list of error codes, see Error responses.

messagestring

A human-readable description of what went wrong.

Example error responses

Expected long for query parameter
{
"code": "bad_query_params",
"message": "Expected long for query parameter `{key}` but found {value}"
}
JSON
The continuation token is invalid or expired.
{
"code": "invalid_field",
"message": "Invalid continuation token"
}
JSON

401 Unauthorized

codestring

A short string indicating what failed. This field can be used to handle errors programmatically. For a complete list of error codes, see Error responses.

messagestring

A human-readable description of what went wrong.

Example error response

Access token could not be decoded or signature could not be verified.
{
"code": "invalid_access_token",
"message": "Access token is invalid"
}
JSON

403 Forbidden

codestring

A short string indicating what failed. This field can be used to handle errors programmatically. For a complete list of error codes, see Error responses.

messagestring

A human-readable description of what went wrong.

Example error response

The caller is not allowed to access design analytics.
{
"code": "permission_denied",
"message": "Not allowed to access analytics for this design"
}
JSON

404 Not Found

codestring

A short string indicating what failed. This field can be used to handle errors programmatically. For a complete list of error codes, see Error responses.

messagestring

A human-readable description of what went wrong.

Example error response

The design was not found, or analytics are unavailable.
{
"code": "design_not_found",
"message": "Design not found or analytics are not available for this design"
}
JSON

429 Too Many Requests

codestring

A short string indicating what failed. This field can be used to handle errors programmatically. For a complete list of error codes, see Error responses.

messagestring

A human-readable description of what went wrong.

Example error response

Rate limit exceeded
{
"code": "too_many_requests",
"message": "Too many requests to {operation}"
}
JSON

Try it out

This uses your live Canva data.

This is not a sandbox/playground. This form performs API requests against your account's actual live Canva data. Make sure that you understand what the request is doing, as well as the requirements for each parameter detailed above.

Step 1: Enter your access token

To get started, generate an access token or provide your own below