API & webhooks

Verifying a webhook endpoint

Overview

Kyvento delivers webhook events exclusively to verified endpoints. Verification establishes that the configured URL is under your control. It follows a challenge-response procedure: Kyvento sends a one-time check value to the endpoint URL, and the endpoint returns that value in the same HTTP response.

This article describes the procedure, the format of the verification request and the expected response. It is intended for the technical contact who operates the endpoint.

An unverified endpoint receives no deliveries, even if it is enabled. This state is indicated in the endpoint list by the "Not verified" badge.

Procedure

  1. Create the endpoint under Settings → "Webhooks". The signing secret is displayed once and must be stored securely. Details: Configuring webhooks.
  2. Prepare the endpoint. The endpoint must recognize verification requests and return the contained check value synchronously (format below).
  3. Trigger verification using the "Verify endpoint" button. Kyvento sends the verification request immediately, evaluates the response within the same operation and displays the result in the interface.

The verification request

Kyvento sends a single POST request to the endpoint URL. Structure and signature match a regular delivery. The request body contains the type endpoint.verification and the field challenge with a 64-character hexadecimal check value:

POST /webhooks/kyvento HTTP/1.1
Host: your-application.example
Content-Type: application/json; charset=utf-8
User-Agent: Kyvento-Webhooks/2.0
X-Kyvento-Event: endpoint.verification
X-Kyvento-Account-Id: 128
X-Kyvento-Delivery-Id: evt_del_verify_yQ3nR7pKmA1vTz8bXsLd
X-Kyvento-Signature: t=1755340800,v1=6f1c8b3a…

{
  "type": "endpoint.verification",
  "challenge": "3f9a1c47b28e5d60a4f7c1938be25d0af6172c8d94e30b5a7fd82169c4e0ab73"
}

The check value is generated anew for each verification and is not stored by Kyvento. The endpoint must return the value from the current request; a cached value from an earlier request is not accepted.

Basic authentication and custom HTTP headers configured for the endpoint are also transmitted with the verification request.

The expected response

The endpoint must respond within the same request with HTTP status 200 and return the check value unchanged. Two response formats are accepted:

Format 1: check value as the response body

HTTP/1.1 200 OK
Content-Type: text/plain

3f9a1c47b28e5d60a4f7c1938be25d0af6172c8d94e30b5a7fd82169c4e0ab73

Format 2: JSON object with the field challenge

HTTP/1.1 200 OK
Content-Type: application/json

{"challenge":"3f9a1c47b28e5d60a4f7c1938be25d0af6172c8d94e30b5a7fd82169c4e0ab73"}

Leading and trailing whitespace or line breaks in the body are ignored. Additional fields in the JSON object are permitted as long as the field challenge is present.

Only HTTP status 200 is accepted. The status codes 202 and 204 are treated as failures because they cannot carry a response body. If your endpoint acknowledges regular deliveries with 204, the type endpoint.verification must be handled separately.

Example implementation

The verification request is handled before regular event processing. The following PHP example can be transferred to any language:

$payload = json_decode(file_get_contents('php://input'), true);

// Verification request: return the check value unchanged.
if (($payload['type'] ?? null) === 'endpoint.verification') {
    header('Content-Type: text/plain');
    http_response_code(200);
    echo $payload['challenge'];
    exit;
}

// Regular event processing.

If your application processes incoming events asynchronously, for example via a queue, the verification request must be excluded from that path. The check value is expected in the response to the same request.

Endpoint requirements

  • Public reachability: addresses in private or reserved network ranges are rejected.
  • Valid TLS certificate: the connection is established over HTTPS. An expired or incomplete certificate causes the request to be aborted.
  • No redirects: HTTP redirects (301, 302) are not followed. Configure the final address.
  • Response time: the response must arrive within 10 seconds. The operation runs synchronously.
  • Signature verification: the verification request carries a valid signature in the X-Kyvento-Signature header. Verifying it is possible but not required for verification. The procedure is described in Configuring webhooks.

Validity of the verification

  • Change of the endpoint URL: the verification is bound to the checked address. After the URL is changed, the endpoint must be verified again; no deliveries are made until then.
  • Failed re-verification: a failed verification attempt does not revoke an existing verification. Temporary unavailability is covered by the regular delivery retries – see Webhook retry and error handling.
  • Rate limit: verification requests are limited to ten per minute per user.

Error messages

Message Cause Action
The address is not publicly reachable The URL points to a private or reserved network. Configure a publicly reachable address.
The endpoint was not reachable Connection error, timeout, DNS resolution or certificate error. Check URL, reachability and certificate.
The endpoint did not respond with status 200 The endpoint responded with a different status code, e.g. 204, 301, 401 or 500. Return status 200 for the type endpoint.verification.
The endpoint did not return the check value The response body did not contain the check value, contained only part of it, or contained a fixed response such as OK. Return the value from the challenge field unchanged.
The address was changed during the check The endpoint URL was edited while verification was in progress. Trigger verification again for the new address.

Checks after successful verification

  1. The endpoint badge changes to "Verified"; the notice about pending verification is no longer displayed.
  2. Trigger a test delivery and confirm that your application processes the sample event.
  3. Confirm the processing of a regular event, for example by creating a test invoice.

Related articles

← Back to Support

Related articles

API & webhooks

Importing data via the REST API

Overview When migrating to Kyvento from another system, you transfer your existing records – customers, subscriptions, s...

API & webhooks

Setting up the Stripe webhook

Overview A webhook is Stripe's way of reporting back to Kyvento: whenever something happens in Stripe that Kyvento needs...

API & webhooks

Setting up the PayPal webhook

Overview A webhook is PayPal's way of reporting back to Kyvento: whenever something happens in PayPal that Kyvento needs...