DocsWebhooks

Webhooks

Last updated: March 27, 2026

1. Overview

Webhooks deliver real-time notifications when events occur in Arkova. Instead of polling the API, your server receives an HTTPS POST the moment something important happens.

  • HTTPS-only delivery (enforced at database level)
  • Every delivery is signed with HMAC-SHA256 for authenticity verification
Note
Webhooks are available on all plans. Configure them in Settings → Webhooks.

2. Setup

  • Navigate to Settings → Webhooks in the Arkova dashboard
  • Click "Add Endpoint"
  • Enter your HTTPS endpoint URL
  • Select which events to subscribe to
  • Copy your webhook signing secret (shown once)
Important
Your endpoint must respond with a 2xx status within 30 seconds. Non-2xx responses trigger retries.

3. Event Types

EventTriggerDescription
anchor.createdNew credential createdFires when an anchor record is created
anchor.securedNetwork confirmationFires when the anchor transaction is confirmed in a block
anchor.revokedCredential revokedFires when a credential is revoked by the owner
anchor.verifiedVerification lookupFires when someone verifies the credential (optional, high volume)
attestation.createdNew attestationFires when an attestation claim is created
attestation.revokedAttestation revokedFires when an attestation is revoked

4. Payload Format

Every webhook delivery sends a JSON body with the following shape:

json
{
  "event": "anchor.secured",
  "timestamp": "2026-03-15T14:30:00Z",
  "data": {
    "public_id": "ARK-2026-00091",
    "status": "SECURED",
    "bitcoin_block": 204567,
    "network_receipt_id": "b8e381df09ca404e...",
    "issuer_name": "University of Michigan",
    "credential_type": "DIPLOMA"
  },
  "idempotency_key": "wh_evt_abc123def456"
}

Headers included on every delivery:

  • X-Arkova-Signature — HMAC-SHA256 signature of the payload body
  • X-Arkova-Timestamp — ISO 8601 UTC timestamp
  • X-Arkova-Event — Event type (e.g., anchor.secured)

5. Signature Verification

Important
Always verify webhook signatures. Reject unsigned or incorrectly signed payloads.

Node.js / TypeScript

typescript
import crypto from 'crypto';

function verifySignature(
  payload: string,
  signature: string,
  secret: string
): boolean {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

Python

python
import hmac
import hashlib

def verify_signature(payload: bytes, signature: str, secret: str) -> bool:
    expected = hmac.new(
        secret.encode(), payload, hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(signature, expected)

6. Retry Policy

AttemptDelayTotal Elapsed
1Immediate0
21 minute1 min
35 minutes6 min
430 minutes36 min
52 hours~2.5 hours
  • After all 5 attempts are exhausted, the event goes to a dead letter queue (retained 30 days)
  • Manual replay is available from the dashboard
  • Consecutive failures trip a circuit breaker — the endpoint is disabled and probed after a cooldown period
  • Rate limit: 100 deliveries/minute per organization

7. Best Practices

  • Return 200 quickly, then process async — don't do heavy work in the handler
  • Use the idempotency_key to deduplicate — the same event may be delivered more than once
  • Verify signatures on every request — never trust unverified payloads
  • Use a queue (Redis, SQS) for processing — decouple receipt from handling
  • Monitor your endpoint's error rate in the Arkova dashboard
  • Set up alerting for webhook failures