Skip to content

Handle webhook events in your application

Receive real-time notifications about authentication events in your application using Scalekit webhooks

Webhooks provide real-time notifications about authentication and user management events in your Scalekit environment. Instead of polling for changes, your application receives instant notifications when users sign up, log in, join organizations, or when other important events occur.


UserScalekitYour AppScalekit SDK Trigger event (login, signup, directory sync) Queue webhook event POST webhook payload Verify webhook signature Process event data Return success response (200/201)

Webhooks enable your app to react immediately to changes in your auth stack through:

  • Real-time updates: Get notified immediately when events occur
  • Reduced API calls: No need to poll for changes
  • Event-driven architecture: Build responsive workflows that react to user actions
  • Reliable delivery: Scalekit ensures webhook delivery with automatic retries

All webhook payloads follow a standardized structure with metadata and event-specific data in the data field.

User created event payload
{
"spec_version": "1", // The version of the event specification format. Currently "1".
"id": "evt_123456789", // A unique identifier for the event (e.g., evt_123456789).
"object": "DirectoryUser", // The type of object that triggered the event (e.g., "DirectoryUser", "Directory", "Connection").
"environment_id": "env_123456789", // The ID of the environment where the event occurred.
"occurred_at": "2024-08-21T10:20:17.072Z", // ISO 8601 timestamp indicating when the event occurred.
"organization_id": "org_123456789", // The ID of the organization associated with the event.
"type": "organization.directory.user_created", // The specific event type (e.g., "organization.directory.user_created").
"data": { // Event-specific payload containing details relevant to the event type.
"user_id": "usr_123456789",
"email": "user@example.com",
"name": "John Doe"
}
}

Set up webhook endpoints and select which events you want to receive through the Scalekit dashboard.

  1. In your Scalekit dashboard, navigate to Settings > Webhooks

  2. Click Add Endpoint and provide:

    • Endpoint URL - Your application’s webhook handler URL (e.g., https://yourapp.com/webhooks/scalekit)
    • Description - Optional description for this endpoint
  3. Choose which events you want to receive from the dropdown:

    • User events - user.created, user.updated, user.deleted
    • Organization events - organization.created, organization.updated
    • Authentication events - session.created, session.expired
    • Membership events - membership.created, membership.updated, membership.deleted

  4. Copy the Signing Secret - you’ll use this to verify webhook authenticity in your application

  5. Use the Send Test Event button to verify your endpoint is working correctly

Create secure webhook handlers in your application to process incoming events from Scalekit.

  1. Create an HTTP POST endpoint in your application to receive webhook payloads from Scalekit.

    Express.js webhook handler
    3 collapsed lines
    import express from 'express';
    import { Scalekit } from '@scalekit-sdk/node';
    const app = express();
    const scalekit = new Scalekit(/* your credentials */);
    // Use raw body parser for webhook signature verification
    app.use('/webhooks/scalekit', express.raw({ type: 'application/json' }));
    app.post('/webhooks/scalekit', async (req, res) => {
    try {
    // Get webhook signature from headers
    const signature = req.headers['scalekit-signature'];
    const rawBody = req.body;
    // Verify webhook signature using Scalekit SDK
    const isValid = await scalekit.webhooks.verifySignature(
    rawBody,
    signature,
    process.env.SCALEKIT_WEBHOOK_SECRET
    );
    if (!isValid) {
    console.error('Invalid webhook signature');
    return res.status(401).json({ error: 'Invalid signature' });
    }
    // Parse and process the webhook payload
    const event = JSON.parse(rawBody.toString());
    await processWebhookEvent(event);
    // Always respond with 200 to acknowledge receipt
    res.status(200).json({ received: true });
    } catch (error) {
    console.error('Webhook processing error:', error);
    res.status(500).json({ error: 'Webhook processing failed' });
    }
    });
  2. Handle different event types based on your application’s needs.

    Process webhook events
    async function processWebhookEvent(event) {
    console.log(`Processing event: ${event.type}`);
    switch (event.type) {
    case 'user.created':
    // Handle new user registration
    await handleUserCreated(event.data.user, event.data.organization);
    break;
    case 'user.updated':
    // Handle user profile updates
    await handleUserUpdated(event.data.user);
    break;
    case 'organization.created':
    // Handle new organization creation
    await handleOrganizationCreated(event.data.organization);
    break;
    case 'membership.created':
    // Handle user joining organization
    await handleMembershipCreated(event.data.membership);
    break;
    default:
    console.log(`Unhandled event type: ${event.type}`);
    }
    }
    async function handleUserCreated(user, organization) {
    // Use case: Sync new user to your database, send welcome email, set up user workspace
    console.log(`New user created: ${user.email} in org: ${organization.display_name}`);
    // Sync to your database
    await syncUserToDatabase(user, organization);
    // Send welcome email
    await sendWelcomeEmail(user.email, user.first_name);
    // Set up user workspace or default settings
    await setupUserDefaults(user.id, organization.id);
    }
  3. Use the Scalekit SDK to verify webhook signatures before processing events.

    Signature verification
    async function verifyWebhookSignature(rawBody, signature, secret) {
    try {
    // Use Scalekit SDK for verification (recommended)
    const isValid = await scalekit.webhooks.verifySignature(rawBody, signature, secret);
    return isValid;
    } catch (error) {
    console.error('Signature verification failed:', error);
    return false;
    }
    }

Scalekit expects specific HTTP status codes in response to webhook deliveries. Return appropriate status codes to control retry behavior.

  1. Return success status codes when webhooks are processed successfully.

    Status CodeDescription
    200 OKWebhook processed successfully
    201 Created RecommendedWebhook processed and resource created
    202 AcceptedWebhook accepted for asynchronous processing
  2. Return error status codes to indicate processing failures.

    Status CodeDescription
    400 Bad RequestInvalid payload or malformed request
    401 UnauthorizedInvalid webhook signature
    403 ForbiddenWebhook not authorized
    422 Unprocessable EntityValid request but cannot process
    500 Internal Server ErrorServer error during processing

Test your webhook implementation locally before deploying to production.

Use ngrok to expose your local development server for webhook testing.

Set up local webhook testing
# Install ngrok
npm install -g ngrok
# Start your local server
npm run dev
# In another terminal, expose your local server
ngrok http 3000
# Use the ngrok URL in your Scalekit dashboard
# Example: https://abc123.ngrok.io/webhooks/scalekit

Webhooks enable common integration patterns:

  • User lifecycle management: Sync user data across systems, provision accounts in downstream services, and trigger onboarding workflows when users sign up or update their profiles
  • Organization and membership management: Set up workspaces when organizations are created, update user access when they join or leave organizations, and provision organization-specific resources
  • Authentication monitoring: Track login patterns, update last-seen timestamps, and trigger security alerts for suspicious activity

You now have a complete webhook implementation that can reliably process authentication events from Scalekit. Consider these additional improvements: