Danvas
Danvas
DashboardSupportWelcome

👤 USER DOCS

User Guides

Getting Started

Getting StartedDashboard & OnboardingApp Settings

Tutorials

Tutorial: Setting Up Shift Tasks & ClosersTutorial: Managing Incidents in the InboxTutorial: Tracking Compliance & Sync StatusTutorial: Operational Workflows with the AI AssistantTutorial: Building & Deploying Custom Checklists

Daily Operations (Staff)

Shift Workspace & TasksService Day SetupDaily Line-UpStaff Service Day ReportsForms

Communication & Chat

Messages & AnnouncementsUnified Operations InboxAI Assistant

Manager & Admin Guides

Daily Line-Up SetupStaff SchedulingManaging LocationsNPS and Guest FeedbackCouponsContacts and Guest HistoryManager CloseoutsDaily Line-Up & ComplianceAnalyticsIncident ReportingWhistleblower Concerns & FeedbackAdmin Tools

⚙️ DEVELOPER DOCS

Getting Started

Getting StartedDevelopmentDeployment Guide

Architecture

Architecture OverviewExplanation: AI Integration & Tenant SecurityExplanation: Dynamic Forms Engine DesignExplanation: Compliance Ledger DesignExplanation: Live Sync & Data FreshnessData FlowArchitecture Decision Records

Core Domain

Core DomainDatabase ReferenceLocations DomainAuth & RBACScheduling DomainReports DomainIncidents DomainUnified Operations InboxLive Sync Data FreshnessToast Sync PipelineNotifications DomainCoupons and Guest NPSAudit Log & Compliance ArchitectureDesign Audit FindingsAI Chat IntegrationAnalytics & Tips Integration

Frontend

Frontend ArchitectureFormsLoading SkeletonsComponentsPWA & Offline ShellScreenshots

API Reference

API Reference

Endpoints

POS Sales APIOptimization Data APISchedule Shifts APIEmployee Export APIReports APIIncidents APIAI Chat APIPush Notifications APIWebhooks APICron API

Contributing

ContributingCode Examples

Security

Security & Compliance

Release Notes

What's New

Webhooks API

Lifecycle event handlers for Clerk and Svix

Danvas exposes webhook endpoints to receive lifecycle events from external services like Clerk (user management).

Clerk webhooks are owned by apps/api at /api/webhooks/clerk. Configure Clerk to deliver lifecycle events only to this canonical receiver.

POST
/api/webhooks/clerk

Authorization

webhookSignature
headersvix-signature<token>

Clerk webhook signature verification

Request Body

application/json
  1. body
  1. body
  2. …
type?string
Value in"user.created""user.updated""user.deleted"
data?

Response Body

Webhook processed

application/json
  1. response
  1. response
  2. …
received?boolean
curl -X POST "https://example.com/api/webhooks/clerk" \
  -H "Content-Type: application/json" \
  -d '{}'
{
  "received": true
}

Security

All webhook endpoints require signature verification to ensure requests originate from a trusted source.

Clerk Signature

Verify the svix-id, svix-timestamp, and svix-signature headers using your CLERK_WEBHOOK_SECRET.

Payload Schemas

Webhook payloads vary by event type. Refer to the specific service documentation for detailed object structures.

Idempotency

Providers may redeliver events. Each receiver uses its owning durable contract; a transport receipt is not proof that a business transition or notification was accepted.

The current Clerk receiver uses command outcomes through @repo/idempotency/command: the verified Svix ID identifies the command, with team/service actor scope and a canonical payload hash. Domain synchronization and command completion follow the receiver's transaction/retry contract. It does not use a generic body-hash webhook example as its business authority.

Coupon automation uses the canonical producer's stable event identity and canonical payload hash. Its bounded legacy compatibility path retains body-hash receipt deduplication through processed_webhooks; that receipt alone cannot prove feedback or authorize a notification. The durable worker boundary below rechecks the records. Retryable receipt failures and permanent dispositions are owned by the route, not an instruction to release any business command.

For command outcomes and provider receipt primitives, see the Idempotency package.

Coupon automation and durable event authority

The separate POST /api/automation/coupons receiver accepts canonical guest-event transport and retains bounded legacy compatibility. Its source owner owns signature/authentication, validation, and compatibility behavior. It is not the public guest activation or survey submission API.

Transport deduplication alone cannot authorize fulfillment or an alert. Canonical messages retain the producer's stable eventId and converge on the existing guest event queue identity. The owning worker reloads authoritative records and decides eligible alerts, lifecycle no-ops, and gated recovery. A legacy rating hint cannot send a notification without the corresponding durable feedback/response identity.

Queue/provider failures do not undo committed domain transitions. Route with the actual team/location and privacy-safe metadata, never Contact values, comments, private/public tokens, cookies, or staff proof. See Coupon and survey delivery.

Related

Clerk Auth & RBAC

Security & Compliance

API Overview

Push Notifications API

Web Push subscription lifecycle and sending endpoints

Cron API

Internal endpoints for scheduled operational tasks

On this page

SecurityClerk SignaturePayload SchemasIdempotencyCoupon automation and durable event authorityRelated