Docs/Account/Guides/Webhooks

Webhooks

Webhooks let you receive real-time HTTP notifications when events occur in your tenant. Instead of polling for changes, register an endpoint and Vyntech Account will POST event payloads to it — signed with HMAC-SHA256 so you can verify authenticity.

How Webhooks Work

When something happens in your tenant — a user registers, a login fails, a session is revoked — Vyntech Account fires an event. If you have a webhook registered for that event type, here's what happens:

  1. 1An event occurs in your tenant (e.g., a user registers).
  2. 2The payload is constructed with full event details and signed using HMAC-SHA256 with your webhook secret.
  3. 3A POST request is sent to your registered endpoint with the payload as JSON body and the signature in the X-Webhook-Signature header.
  4. 4Your endpoint must respond with a 2xx status within 10 seconds.
  5. 5If delivery fails, the system retries with exponential backoff (up to 3 attempts).

Tip: Keep your webhook handler fast — acknowledge the request immediately and process the event asynchronously. Heavy processing inside the handler risks timeouts and unnecessary retries.

Event Types

Subscribe to specific events or use * to receive all events. Events follow a resource.action naming convention.

EventDescription
Users
user.registeredA new user registered in the tenant
user.updatedUser profile or status was modified
user.deletedUser was permanently deleted
Authentication
auth.loginSuccessful login (password + optional MFA)
auth.login.failedFailed login attempt (bad password or MFA)
auth.logoutUser logged out
auth.mfa_enabledUser enabled MFA
auth.mfa_disabledUser or admin disabled MFA
auth.password_changedUser changed their password
auth.password_resetPassword was reset via email flow
Sessions
session.createdNew session created after successful login
session.revokedSession was revoked (by user, admin, or system)
Risk Engine
risk.challenge_triggeredRisk score triggered a step-up challenge
risk.login_blockedLogin was blocked due to high risk score
Settings & API Keys
settings.updatedTenant settings were modified
api_key.createdNew API key was created
api_key.revokedAPI key was revoked

Payload Format

Every webhook delivery sends a JSON payload with a consistent structure. TheX-Webhook-Signature header contains the HMAC-SHA256 signature of the raw request body.

Headers

Content-Typeapplication/json
X-Webhook-Signaturesha256=<hex-encoded HMAC>
X-Webhook-IDUnique delivery ID (for idempotency)
X-Webhook-TimestampUnix timestamp of delivery attempt

Example Payload

POST to your endpoint
{
  "id": "evt_01H9ABCD4F2B7NQ9RPWT3M6J",
  "event": "user.registered",
  "tenant_id": "tnt_01H7ABCD5E3C8MR0QPXS4N7K",
  "timestamp": "2024-11-15T09:32:17Z",
  "data": {
    "user_id": "usr_01H8KXYZ4F2B7NQ9RPWT3M6J",
    "email": "jane@acme-corp.com",
    "display_name": "Jane Smith",
    "status": "active",
    "email_verified": false,
    "mfa_enabled": false
  }
}
idUnique event ID — use for idempotency checks
eventThe event type (e.g., user.registered)
tenant_idWhich tenant this event belongs to
timestampISO 8601 timestamp of when the event occurred
dataEvent-specific payload (varies by event type)

Registering a Webhook

Register a webhook endpoint by providing the target URL, the events you want to subscribe to, and an optional secret for signature verification. If you don't provide a secret, one will be generated for you.

POST/api/v1/webhooks🔒 Auth

Register a new webhook endpoint for your tenant.

curl -X POST https://id.vyntech.com.au/api/v1/webhooks \ -H "Authorization: Bearer eyJhbGciOiJFZERTQSIs..." \ -H "Content-Type: application/json" \ -d '{ "url": "https://your-app.com/webhooks/vyntech", "events": ["user.registered", "auth.login", "auth.login.failed"], "secret": "whsec_your_shared_secret_here" }'
Request Body
{
  "url": "https://your-app.com/webhooks/vyntech",
  "events": ["user.registered", "auth.login", "auth.login.failed"],
  "secret": "whsec_your_shared_secret_here"
}

Important:The secret is only returned once at creation time. Store it securely — you'll need it to verify incoming webhook signatures. If you lose it, you must rotate the webhook secret.

Signature Verification

Every webhook delivery includes an X-Webhook-Signatureheader containing a HMAC-SHA256 signature of the raw request body, computed with your shared secret. Always verify this signature before processing the event to ensure the request came from Vyntech Account and wasn't tampered with.

How It Works

  1. 1Read the raw request body (do not parse JSON first — the signature is over the raw bytes).
  2. 2Compute HMAC-SHA256 of the raw body using your webhook secret as the key.
  3. 3Compare your computed signature with the value in X-Webhook-Signature (after stripping the sha256= prefix).
  4. 4Use a constant-time comparison to prevent timing attacks.

Verification Examples

POSTYour webhook endpointPublic

Verify the X-Webhook-Signature header before processing events.

# Verify signature manually with openssl BODY='{"id":"evt_01H9ABCD...","event":"user.registered",...}' SECRET="whsec_your_shared_secret_here" EXPECTED=$(echo -n "$BODY" | openssl dgst -sha256 -hmac "$SECRET" | cut -d' ' -f2) echo "sha256=$EXPECTED" # Compare with the X-Webhook-Signature header value

Security warning: Never skip signature verification in production. Without it, any attacker who discovers your webhook URL can send fake events to your system. Always use constant-time comparison to prevent timing attacks.

Retry Policy

If your endpoint doesn't respond with a 2xx status within 10 seconds, or if the connection fails, Vyntech Account will retry delivery with exponential backoff.

AttemptDelayDescription
1st retry10 secondsImmediate retry for transient failures
2nd retry60 secondsShort cooldown
3rd retry300 secondsFinal attempt (5 minutes)

Failure Escalation

  • After 3 consecutive failures for a single event, the delivery is marked as failed and won't be retried.
  • If a webhook accumulates failures over time, it's marked as failing — events continue to be sent but you'll see warnings in the admin dashboard.
  • After 24 hours of continuous failures, the webhook is automatically disabled. You'll receive an email notification and must re-enable it manually.

Check Webhook Status

GET/api/v1/webhooks/:id🔒 Auth

Get the current status and delivery stats for a webhook.

curl https://id.vyntech.com.au/api/v1/webhooks/whk_01H9WXYZ4F2B7NQ9RPWT3M6J \ -H "Authorization: Bearer eyJhbGciOiJFZERTQSIs..."

Testing Webhooks

Before going live, you can send a test event to your webhook endpoint. The test endpoint sends a synthetic event with event: "webhook.test"to verify your endpoint is reachable and responding correctly.

POST/api/v1/webhooks/:id/test🔒 Auth

Send a test event to verify your webhook endpoint is working.

curl -X POST https://id.vyntech.com.au/api/v1/webhooks/whk_01H9WXYZ4F2B7NQ9RPWT3M6J/test \ -H "Authorization: Bearer eyJhbGciOiJFZERTQSIs..."

Development tip: Use a tool like ngrok or webhook.site to expose your local development server to the internet for testing webhooks.

Best Practices

Respond quickly, process asynchronously

Return a 200 immediately and enqueue the event for background processing. Your endpoint has a 10-second timeout — if processing takes longer, the delivery will be marked as failed and retried unnecessarily.

Always verify signatures

Never skip HMAC verification, even in staging environments. It takes one line of code and prevents entire classes of security vulnerabilities. Use constant-time comparison to prevent timing attacks.

Use idempotency keys

The id field in the event payload is unique. Store processed event IDs and skip duplicates. Retries will resend the same event ID, so idempotency prevents double-processing.

Handle out-of-order delivery

Webhooks are delivered at-least-once but not necessarily in order. A user.updated event might arrive before user.registered due to retries. Use the timestamp field to determine event ordering and ignore stale updates.

Monitor webhook health

Set up alerts for failed deliveries. Use the GET /api/v1/webhooks/:id endpoint to check delivery stats periodically. If your webhook gets disabled after 24h of failures, you'll miss events until you fix the issue and re-enable it.

What's Next

We use cookies and similar technologies to measure traffic and improve the site. You can choose which categories to allow. Manage Preferences.