> ## 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 the public keys for webhooks API reference for the keys method. 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. The Keys API (`connect/keys`) is a security measure you can use to verify the authenticity of webhooks you receive from the Canva REST APIs. The Keys API returns a [JSON Web Key (JWK)](https://www.rfc-editor.org/rfc/rfc7517#section-2), which you can use to decrypt the webhook signature and verify it came from Canva and not a potentially malicious actor. This helps to protect your systems from [Replay attacks](https://owasp.org/Top10/A08_2021-Software_and_Data_Integrity_Failures/). The keys returned by the Keys API can rotate. We recommend you cache the keys you receive from this API where possible, and only access this API when you receive a webhook signed with an unrecognized key. This allows you to verify webhooks quicker than accessing this API every time you receive a webhook. ## HTTP method and URL path GET https\://api.canva.com/rest/v1/connect/keys ## Authentication and authorization This endpoint is public and doesn't require authentication. ## Example request Examples for using the `/v1/connect/keys` endpoint: ```sh curl --request GET 'https://api.canva.com/rest/v1/connect/keys' ``` ```js const fetch = require("node-fetch"); fetch("https://api.canva.com/rest/v1/connect/keys", { method: "GET", }) .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/connect/keys")) .method("GET", HttpRequest.BodyPublishers.noBody()) .build(); HttpResponse response = HttpClient.newHttpClient().send( request, HttpResponse.BodyHandlers.ofString() ); System.out.println(response.body()); } } ``` ```py import requests response = requests.get("https://api.canva.com/rest/v1/connect/keys"); 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/connect/keys"), }; 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/connect/keys" req, _ := http.NewRequest("GET", url, nil) 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/connect/keys", CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_RETURNTRANSFER => true, )); $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/connect/keys') http = Net::HTTP.new(url.host, url.port) http.use_ssl = true request = Net::HTTP::Get.new(url) 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: A Json Web Key Set (JWKS) with public keys used for signing webhooks. You can use this JWKS to verify that a webhook was sent from Canva. Properties of keys} defaultExpanded={true}> The `kid` (key ID) is a unique identifier for a public key. When the keys used to sign webhooks are rotated, you can use this ID to select the correct key within a JWK Set during the key rollover. The `kid` value is case-sensitive. The `kty` (key type) identifies the cryptographic algorithm family used with the key, such as "RSA" or "EC". Only Octet Key Pairs (`OKPs`) are supported. The `kty` value is case-sensitive. For more information on the `kty` property and OKPs, see [RFC-8037 — "kty" (Key Type) Parameter](https://www.rfc-editor.org/rfc/rfc8037.html#section-2). The `crv` (curve) property identifies the curve used for elliptical curve encryptions. Only "Ed25519" is supported. For more information on the `crv` property, see [RFC-8037 — Key Type "OKP"](https://www.rfc-editor.org/rfc/rfc8037.html#section-2). The `x` property is the public key of an elliptical curve encryption. The key is Base64urlUInt-encoded. For more information on the `x` property, see [RFC-8037 — "x" (X Coordinate) Parameter](https://www.rfc-editor.org/rfc/rfc8037#section-2). ## Example response ```json { "keys": [ { "kid": "a418dc7d-ecc5-5c4b-85ce-e1104a8addbe", "kty": "OKP", "crv": "Ed25519", "x": "aIQtqd0nDfB-ug0DrzZbwTum-1ITdXvKxGFak_1VB2j" }, { "kid": "c8de5bec1-1b88-4ddaae04acc-ce415-5d7", "kty": "OKP", "crv": "Ed25519", "x": "m2d1FT-gfBXxIzKwdQVTra0D-aBq_ubZ1jI0GuvkDtn" } ] } ```