Webhooks
Inbound webhook endpoints for external integrations
Struere provides webhook endpoints for receiving events from external services. These endpoints are registered in the Convex HTTP router and process incoming events to keep your platform synchronized with third-party systems.
Clerk Webhook
Endpoint: POST /webhook/clerk
Receives user, organization, and membership events from Clerk to keep the Struere database in sync with your authentication provider.
Supported Event Types
| Event Type | Action |
|---|---|
user.created |
Creates or updates the user record in Struere |
user.updated |
Updates the user's email and name |
organization.created |
Creates the organization in Struere |
organization.updated |
Updates the organization's name and slug |
organization.deleted |
Marks the organization as deleted |
organizationMembership.created |
Links a user to an organization with their role |
organizationMembership.updated |
Updates the user's role within the organization |
organizationMembership.deleted |
Removes a user's membership from the organization |
Role Mapping
Clerk roles are mapped to Struere roles:
| Clerk Role | Struere Role |
|---|---|
org:admin |
admin |
org:owner |
admin |
| All other roles | member |
Setup
Configure the Clerk webhook in your Clerk Dashboard:
- Navigate to Webhooks in the Clerk Dashboard
- Create a new endpoint pointing to
https://your-deployment.convex.site/webhook/clerk - Select the event types listed above
- Save the endpoint
Response
Returns 200 with {"received": true} on success, or 500 if processing fails.
WhatsApp Webhooks (Kapso)
WhatsApp integration uses the Kapso service as an intermediary. Two webhook endpoints handle different aspects of the WhatsApp connection.
Project Webhook
Endpoint: POST /webhook/kapso/project
Receives phone number connection events when a WhatsApp number is linked through the Kapso setup flow.
Authentication: HMAC-SHA256 signature verification via the X-Kapso-Signature header. The signature is computed over the raw request body using the KAPSO_WEBHOOK_SECRET environment variable.
Event Types:
| Event Type | Action |
|---|---|
whatsapp.phone_number.created |
Updates the WhatsApp connection status to connected and registers the message webhook |
When a phone number is connected, the system:
- Finds the matching WhatsApp connection by Kapso customer ID
- Stores the Kapso phone number ID and phone number
- Sets the connection status to
connected - Registers the messages webhook URL with Kapso for that phone number
Messages Webhook
Endpoint: POST /webhook/kapso/messages
Receives inbound WhatsApp messages and message status updates.
Authentication: HMAC-SHA256 signature verification via the X-Kapso-Signature header.
Event Types:
| Event Type | Action |
|---|---|
whatsapp.message.received |
Processes and stores the inbound message, routes to assigned agent |
whatsapp.message.status_update |
Updates the delivery status of an outbound message |
Inbound Message Flow
When an inbound message arrives:
- The phone number ID is used to look up the WhatsApp connection and determine the organization
- The message is stored in the
whatsappMessagestable with deduplication bymessageId - If the message is new and contains text,
scheduleAgentRoutingis called - The agent routing mutation finds the connected agent and schedules
routeInboundToAgent - The routing action creates or reuses a thread with
externalIdset towhatsapp:{phoneNumber} - The agent processes the message via
chatAuthenticatedusing a system actor context - The agent's response is sent back via the Kapso API
Status Updates
Status updates (sent, delivered, read, failed) are applied to the matching outbound message record.
Required Environment Variables
| Variable | Description |
|---|---|
KAPSO_WEBHOOK_SECRET |
Shared secret for HMAC signature verification |
Flow Payment Webhook
Endpoint: POST /webhook/flow
Receives payment status updates from the Flow payment provider via form-encoded POST data.
Request Format
The webhook receives a token parameter via application/x-www-form-urlencoded form data. This token is used to verify the payment status with the Flow API.
Processing Flow
- Extract the
tokenfrom the form data - Query all active Flow integration configurations
- For each configuration, call Flow's payment verification API with the token
- Based on the returned status:
| Flow Status | Action |
|---|---|
2 (Paid) |
Mark the payment entity as paid with the current timestamp |
3 (Rejected) |
Mark the payment entity as failed with the status message |
4 (Cancelled) |
Mark the payment entity as failed with the status message |
Response
Always returns 200 OK to acknowledge receipt of the webhook.
Polar Webhook
Endpoint: POST /webhook/polar
Receives payment events from the Polar billing platform.
Authentication: Standard Webhook Signature verification using webhook-id, webhook-timestamp, and webhook-signature headers. The signature is verified against the POLAR_WEBHOOK_SECRET environment variable. Timestamps older than 5 minutes are rejected.
Event Types:
| Event Type | Action |
|---|---|
order.paid |
Adds credits to the organization's account based on the order subtotal amount |
Required Environment Variables
| Variable | Description |
|---|---|
POLAR_WEBHOOK_SECRET |
Secret key for webhook signature verification |
Webhook Security
All webhooks that handle sensitive operations use signature verification:
| Webhook | Verification Method |
|---|---|
| Clerk | Configured in Clerk Dashboard (Svix signatures) |
| Kapso (WhatsApp) | HMAC-SHA256 via X-Kapso-Signature header |
| Flow | Token-based verification via Flow API callback |
| Polar | Standard Webhook Signature (HMAC-SHA256 with base64) |