> ## Documentation Index > Fetch the complete documentation index at: https://www.canva.dev/docs/apps/llms.txt > Use this file to discover all available pages before exploring further. # Get design analytics Get analytics for a design, including total views and viewers. 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](https://www.canva.dev/docs/apps/rest-apis/versions/). * Public apps 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 app must act on behalf of a user who is a member of a [Canva Enterprise](https://www.canva.com/enterprise/) organization. Gets the aggregated analytics for a design. The response includes total views, unique viewers, and view duration metrics. ## HTTP method and URL path GET https\://api.canva.com/rest/v1/designs/\{designId}/analytics This operation is rate limited to 100 requests per minute for each user of your app. ## Authentication and authorization This endpoint requires a valid access token that acts on behalf of a user. For more information, see [Generate an access token](/docs/apps/rest-apis/reference/authentication/generate-access-token). ### Scopes The access token must have all the following [scopes](/docs/apps/rest-apis/scopes) (permissions): * `design:content:read` ### Capabilities The user must have at least one of the following [capabilities](/docs/apps/rest-apis/capabilities/): * `analytics` ## Header parameters Provides credentials to authenticate the request, in the form of a `Bearer` token. For example: `Authorization: Bearer {token}` ## Path parameters The design ID. ## Example request Examples for using the `/v1/designs/{designId}/analytics` endpoint: ```sh curl --request GET 'https://api.canva.com/rest/v1/designs/{designId}/analytics' \ --header 'Authorization: Bearer {token}' ``` ```js const fetch = require("node-fetch"); fetch("https://api.canva.com/rest/v1/designs/{designId}/analytics", { method: "GET", headers: { "Authorization": "Bearer {token}", }, }) .then(async (response) => { const data = await response.json(); console.log(data); }) .catch(err => console.error(err)); ``` ```java 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")) .header("Authorization", "Bearer {token}") .method("GET", HttpRequest.BodyPublishers.noBody()) .build(); HttpResponse response = HttpClient.newHttpClient().send( request, HttpResponse.BodyHandlers.ofString() ); System.out.println(response.body()); } } ``` ```py import requests headers = { "Authorization": "Bearer {token}" } response = requests.get("https://api.canva.com/rest/v1/designs/{designId}/analytics", headers=headers ) print(response.json()) ``` ```csharp 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"), Headers = { { "Authorization", "Bearer {token}" }, }, }; using (var response = await client.SendAsync(request)) { response.EnsureSuccessStatusCode(); var body = await response.Content.ReadAsStringAsync(); Console.WriteLine(body); }; ``` ```go package main import ( "fmt" "io" "net/http" ) func main() { url := "https://api.canva.com/rest/v1/designs/{designId}/analytics" 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)) } ``` ```php $curl = curl_init(); curl_setopt_array($curl, array( CURLOPT_URL => "https://api.canva.com/rest/v1/designs/{designId}/analytics", 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; } ``` ```ruby require 'net/http' require 'uri' url = URI('https://api.canva.com/rest/v1/designs/{designId}/analytics') 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 ``` ## Success response If successful, the endpoint returns a `200` response with a JSON body with the following parameters: The number of unique viewers. The total number of views. The average view duration in seconds. The total view duration in seconds. ## Example response ```json { "average_view_duration_seconds": 42, "total_view_duration_seconds": 5040, "unique_view_count": 87, "total_view_count": 120 } ``` ## Error responses ### 400 Bad Request 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](/docs/apps/rest-apis/error-responses/). A human-readable description of what went wrong. #### Example error response ##### The design ID does not match the expected format. ```json { "code": "invalid_field", "message": "designId does not match expected format" } ``` ### 401 Unauthorized 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](/docs/apps/rest-apis/error-responses/). A human-readable description of what went wrong. #### Example error response ##### Access token could not be decoded or signature could not be verified. ```json { "code": "invalid_access_token", "message": "Access token is invalid" } ``` ### 403 Forbidden 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](/docs/apps/rest-apis/error-responses/). A human-readable description of what went wrong. #### Example error response ##### The caller is not allowed to access design analytics. ```json { "code": "permission_denied", "message": "Not allowed to access analytics for this design" } ``` ### 404 Not Found 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](/docs/apps/rest-apis/error-responses/). A human-readable description of what went wrong. #### Example error response ##### The design was not found, or analytics are unavailable. ```json { "code": "design_not_found", "message": "Design not found or analytics are not available for this design" } ``` ### 429 Too Many Requests 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](/docs/apps/rest-apis/error-responses/). A human-readable description of what went wrong. #### Example error response ##### Rate limit exceeded ```json { "code": "too_many_requests", "message": "Too many requests to {operation}" } ```