Developers

Webhooks and signatures

Get a signed notification the moment a certificate is issued, transferred, revoked or reactivated, with the full certificate in every event.

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

  1. Add your URL

    In Settings → Integrations & notifications, enter an Outbound webhook URL starting with https://.
  2. Choose the full format

    Set Webhook format to Full details, including revoked and reactivated events (v2).
  3. Create a signing secret

    Choose Create signing secret and save it on your server, so you can confirm each message really came from Authentica.
  4. Save

    Events start straight away.

Events

eventSent when
issuedA certificate is created, from an order, by hand or by import.
verifiedThe certificate is opened for the first time.
transferredOwnership moves to a new owner.
reportedSomeone reports a problem from the verification page.
revokedA refund, a cancellation, or you revoke it in the app.
reactivatedA 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 2xx status 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 issued then verified). Saving by certificate.id handles this automatically.
  • Klaviyo events and Shopify Flow triggers are separate and unchanged by the webhook format.

Plan required


Related articles

Not on Shopify yet?

Start a free Shopify trial, then add Miko apps when you are ready.

Set up your store in minutes and try it with your own products. Loyalty, wholesale pricing, AI descriptions and the rest of the Miko apps install in one click once your store is live.