Webhooks send your server a message the moment something happens to a certificate, so your site can update instantly instead of asking the API on a timer.
Turn on webhooks
Add your URL
In Settings → Integrations & notifications, enter an Outbound webhook URL starting withhttps://.Choose the full format
Set Webhook format to Full details, including revoked and reactivated events (v2).Create a signing secret
Choose Create signing secret and save it on your server, so you can confirm each message really came from Authentica.Save
Events start straight away.
Events
| event | Sent when |
|---|---|
issued | A certificate is created, from an order, by hand or by import. |
verified | The certificate is opened for the first time. |
transferred | Ownership moves to a new owner. |
reported | Someone reports a problem from the verification page. |
revoked | A refund, a cancellation, or you revoke it in the app. |
reactivated | A revoked certificate is made valid again. |
What you receive
POST https://your-site.example/authentica-webhook
Content-Type: application/json
X-Authentica-Signature: sha256=5d41402abc4b2a76b9719d911017c592...
{
"version": 2,
"event": "revoked",
"shop": "your-store.myshopify.com",
"occurredAt": "2026-10-06T10:00:00.000Z",
"certificate": { ... }
}
certificate is the same object the API returns, with its new state. The simplest handling is to save it by certificate.id, replacing whatever you had.
Check the signature
With a signing secret set, every message carries X-Authentica-Signature: an HMAC-SHA256 of the raw request body using your secret. Reject anything that doesn't match.
// PHP (WordPress)
$body = file_get_contents('php://input');
$expected = 'sha256=' . hash_hmac('sha256', $body, AUTHENTICA_WEBHOOK_SECRET);
$given = $_SERVER['HTTP_X_AUTHENTICA_SIGNATURE'] ?? '';
if (!hash_equals($expected, $given)) { http_response_code(401); exit; }
$event = json_decode($body, true);
// Node.js (use the raw body, before any JSON parsing)
const crypto = require('crypto');
const expected = 'sha256=' + crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
const given = req.headers['x-authentica-signature'] || '';
const ok = given.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(given), Buffer.from(expected));
Delivery
- Reply with any
2xxstatus within 8 seconds. Do slow work after replying. - Messages are sent once and not retried. If your server was down, catch up with the API using
updated_since. Running that catch-up every hour or so is a good safety net. - The same certificate can arrive more than once (for example
issuedthenverified). Saving bycertificate.idhandles this automatically. - Klaviyo events and Shopify Flow triggers are separate and unchanged by the webhook format.
Plan required
Related articles