---
title: "Verifying webhooks — Anis Developers"
description: "Verify the exact webhook body, destination, application, time and signing-key purpose."
url: https://developers.anis.ly/docs/verifying-webhooks/
language: en
---

> Every page of this documentation: https://developers.anis.ly/llms.txt

# Verifying webhooks

Keep the raw request bytes until verification finishes. A webhook is an incoming request from Anis, with its own signature profile. Its signature is not the request-bound answer profile.

## The signed components

Use RFC 9421, label `sig1`, algorithm `ecdsa-p256-sha256`, and tag `anis-partner-webhook-v1`. Require these covered components in this exact order:

```text
@method @target-uri content-digest webhook-id anis-webhook-attempt anis-application-id
```

The following header example illustrates the profile; the signature placeholder is not a test vector.

```http
Signature-Input: sig1=("@method" "@target-uri" "content-digest" "webhook-id" "anis-webhook-attempt" "anis-application-id");created=1792483200;expires=1792483500;keyid="partner-webhook-signing/0123456789abcdef0123456789abcdef";alg="ecdsa-p256-sha256";tag="anis-partner-webhook-v1"
Signature: sig1=:<base64 of the 64-byte P1363 signature>:
```

`@method` is uppercase POST. `@target-uri` is your configured full HTTPS URL, including its query if present. Header names are case insensitive; component identifiers in the signature are lower case. `Content-Digest` is `sha-256=:<standard base64 SHA-256 of the exact body bytes>:`. Base lines are UTF-8 joined by LF with no final LF. The signature is the fixed 64-byte P1363 r-then-s form, standard base64, not DER or base64url.

## Verify before acting

1. Require both Signature-Input and Signature, exactly one signature label, the exact algorithm, tag and ordered component list.
2. Compute the digest from the received raw body, before JSON parsing or reserialization, and require it to match Content-Digest.
3. Require the configured full target URL, your application id and POST method.
4. Check Unix-second times against a synchronized clock: `expires-created == 300`, `abs(now-created) <= 300`, and `now <= expires`. There is no extra grace after expiry. Each delivery attempt is freshly signed.
5. Fetch `/.well-known/partner-signing-keys.json` over HTTPS from your Anis deployment. Match the exact opaque kid, require `purpose: "webhook"`, status active or next, and `notBefore <= created`. Reject retired or compromised keys and any matching revoked entry. Refuse a key document containing private key material.
6. Rebuild the signature base from the actual request and parameters, and verify the 64-byte signature with that public key. Do not trust a supplied component list without comparing it to the frozen list.
7. Only then parse the envelope, require id to equal webhook-id and applicationId to equal anis-application-id, handle the verified notification and deduplicate its event id.

The same key document also publishes answer keys with `purpose: "answer"`. A key’s presence alone does not authorize it to verify webhooks. The webhook key is separate from the answer-signing key. Do not apply the answer profile’s `@status`, `;req` or 60-second freshness rule to incoming webhooks.

## Accept a delivery once

After verification, durably record the event and process it once. Return a 2xx within ten seconds. Repeated verified deliveries of the same event id should also receive 2xx. Do not deduplicate unverified requests, which could otherwise suppress a genuine event.

A verification notification uses the same signature checks; echo only the verified challenge, as described in [Webhooks](https://developers.anis.ly/docs/webhooks.md). A test notification also uses this profile. Neither creates a purchase.

## SDK support and test examples

SDK 2.2.0 verifies webhooks in .NET, Node.js, PHP and Python; SDK 2.1.0 does not. Follow this profile and the published [signing test vectors](https://developers.anis.ly/docs/test-vectors.md). API answer verification remains a separate check.

[Verifying API answers](https://developers.anis.ly/docs/verifying-answers.md) · [Webhooks](https://developers.anis.ly/docs/webhooks.md)
