---
title: "List Webhook Public Keys"
method: GET
path: "/v1/webhooks-keys"
tags: ["Webhooks"]
---

# List Webhook Public Keys

`GET /v1/webhooks-keys`

Use these keys to verify the authenticity of webhook deliveries by validating the EdDSA-Ed25519 signature.

## Webhook Delivery Headers

Every webhook delivery includes these HTTP headers:
- `Content-Type`: `application/json`
- `x-kiwify-digital-signature`: Base64url-encoded signature (no padding)
- `x-kiwify-timestamp`: Unix timestamp in milliseconds when the webhook was signed

## Signature Verification Process

1. Extract the signature and timestamp from the webhook headers
2. Fetch the active public key from this endpoint (cache it for 24 hours)
3. Reconstruct the signed message using the PoP format:
   ```
   {path}:POST:{body}:{timestamp}
   ```
   Where:
   - `{path}` is only the path portion of your registered webhook URL (e.g., `/webhooks/kiwibank`)
   - `POST` is the HTTP method (always POST for webhooks)
   - `{body}` is the raw compact JSON body (as received, without re-serialization)
   - `{timestamp}` is the value from the `x-kiwify-timestamp` header

4. SHA-256 hash the message bytes, then verify the signature using EdDSA-Ed25519 with the public key
5. Validate the timestamp is within 5 minutes of current time (replay attack protection)

## Response Format
- Returns public keys ordered by creation date (newest first), paginated via cursor
- The `isActive` field indicates the currently active signing key (use this one for verification)
- The `algorithm` field confirms the signing algorithm (EdDSA-Ed25519)
- Use `next_cursor` to fetch the next page when present

Requires `ManageWebhooks` permission.

## Query parameters

- `limit` integer, nullable
- `cursor` string, nullable

## Response `200`

List of public keys for webhook signature verification

- WebhookPublicKeysResponse — Response containing the list of webhook public keys.
  - `next_cursor` string, nullable — Cursor for next page (null if no more results).
  - `public_keys` WebhookPublicKeyDto[], required — List of public keys used for webhook signature verification.
    - `algorithm` string, required — Signing algorithm used.
    - `content` string, required — PEM-encoded public key content.
    - `created_at` string, date-time, required — Timestamp when the key was created (UTC, RFC 3339).
    - `id` integer, required — Unique identifier of the public key.
    - `is_active` boolean, required — Whether this key is currently active.

## Other responses

- `400` — Invalid query parameters (e.g., invalid cursor format, limit out of range)
- `401` — Authentication failed - invalid or missing service account credentials
- `403` — Access denied - service account requires ManageWebhooks permission
- `500` — Internal server error. Error code: INTERNAL_ERROR

---

[API](https://skmtc.net/kiwify/apis/conta-digital-api.md) · [All operations](https://skmtc.net/kiwify/apis/conta-digital-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/kiwify/conta-digital-api/revisions/5e009b25c245/schema)
