Skip to main content
Replyke can call your server when things happen in your project. There are two webhook systems:
  • Project webhooks — broadcast and validation events for the project as a whole, configured once in the project dashboard.
  • Space digest webhooks — a separate per-space delivery system that sends a daily activity digest to a URL you configure on each space individually.
Both use HTTP POST with HMAC-SHA256 signatures, but they are configured and behave independently.

Configuration

Webhooks are configured per project in the dashboard. You need to set:
  • Webhook URL — the endpoint on your server that Replyke will call
  • Webhook secret — a shared secret used to sign outgoing requests and verify incoming responses
  • Subscribed events — the specific event types you want to receive (you only get called for events you opt into)

Event Types

Broadcast Events (Non-blocking)

These fire after an operation completes. Your server is notified but the original operation is not affected by your response.
EventFires when
user.created.completeA new user has been created
user.updated.completeA user’s profile has been updated
entity.created.completeA new entity has been created
entity.updated.completeAn entity has been updated
comment.created.completeA new comment has been created
comment.updated.completeA comment has been updated
space.created.completeA new space has been created
space.updated.completeA space has been updated
message.created.completeA new chat message has been sent
notification.createdAn app notification was created for a user
The notification.created event is the primary mechanism for bridging Replyke’s in-app notification system to push notifications, email, or any other delivery channel your app uses.

Validation Events (Blocking)

These fire before an operation is committed. Replyke waits for your response. If you respond with { "valid": true }, the operation proceeds. Any other response (or no response) causes the operation to be rejected.
EventFires when
user.createdA new user is about to be created
user.updatedA user profile is about to be updated
entity.createdA new entity is about to be created
entity.updatedAn entity is about to be updated
comment.createdA new comment is about to be created
comment.updatedA comment is about to be updated
space.createdA new space is about to be created
space.updatedA space is about to be updated
message.createdA chat message is about to be sent
If no webhook is configured for your project, or if an event type is not in your subscribed list, all validation webhooks pass automatically — your server does not need to be present for your project to function.
Validation webhooks are synchronous. A slow or unavailable webhook endpoint will block the operation and cause it to fail. Ensure your webhook handler is fast and reliable.

Payload Format

All webhook deliveries use the same envelope:
{
  "type": "notification.created",
  "projectId": "your-project-id",
  "stage": "complete",
  "data": { ... }
}
FieldDescription
typeThe event type string (see tables above)
projectIdYour Replyke project ID
stageLifecycle stage of the event
dataThe event payload — the created/updated object or notification data

Signature Verification

Every webhook request includes two headers that allow you to verify the request came from Replyke and has not been tampered with.
HeaderValue
X-SignatureHMAC-SHA256 hex digest of {timestamp}.{JSON.stringify(payload)}
X-TimestampUnix timestamp in milliseconds
To verify on your server:
1

Read the headers

Extract X-Signature and X-Timestamp from the incoming request.
2

Recompute the expected signature

Compute: HMAC-SHA256(webhookSecret, "{timestamp}.{JSON.stringify(body)}") as a hex string, where timestamp is the value from X-Timestamp and body is the raw JSON body.
3

Compare using a constant-time comparison

Compare the expected signature to the received X-Signature. Use a constant-time comparison function to prevent timing attacks.
4

Reject if the signatures do not match

Return a non-2xx response. Do not process the request.
import crypto from "crypto";

function verifyWebhookSignature(
  body: unknown,
  receivedSignature: string,
  timestamp: string,
  secret: string
): boolean {
  const expected = crypto
    .createHmac("sha256", secret)
    .update(`${timestamp}.${JSON.stringify(body)}`)
    .digest("hex");

  return crypto.timingSafeEqual(
    Buffer.from(expected, "hex"),
    Buffer.from(receivedSignature, "hex")
  );
}

Responding to Validation Events

For validation webhooks, your server must respond with a signed JSON body indicating whether the operation should proceed. To allow the operation:
{ "valid": true }
To reject the operation:
{ "valid": false, "message": "Reason for rejection" }
Your response must include an X-Response-Signature header:
X-Response-Signature: HMAC-SHA256(webhookSecret, JSON.stringify(responseBody))
function signWebhookResponse(body: unknown, secret: string): string {
  return crypto
    .createHmac("sha256", secret)
    .update(JSON.stringify(body))
    .digest("hex");
}

// In your handler:
const responseBody = { valid: true };
res.setHeader("X-Response-Signature", signWebhookResponse(responseBody, webhookSecret));
res.json(responseBody);
If the response signature is missing or invalid, Replyke treats the validation as failed and rejects the operation — even if the body contained { "valid": true }.

Common Use Cases

Push Notification Bridge

Subscribe to notification.created. When your webhook receives it, forward the notification to your push provider (FCM, APNs, Expo, OneSignal, etc.) for the target user. The data field contains the notification parameters including the recipient user ID, notification type, and any associated entity or comment.

Content Moderation Gate

Subscribe to comment.created or entity.created (validation events). In your handler, check the content against a blocklist or moderation API. Return { "valid": false } to reject content that fails your rules before it is ever stored.

Audit Logging

Subscribe to broadcast complete events (user.created.complete, entity.created.complete, etc.) to maintain an external audit log or pipe activity into an analytics system or data warehouse.

Space Digest Webhooks

The space digest system is separate from project webhooks. Each space can be configured with its own digest webhook URL and secret, independent of the project-level webhook settings. When the digest is enabled for a space, Replyke sends a daily summary of the past 24 hours of activity to that space’s digest webhook URL. The cron runs hourly and delivers the digest at the configured schedule hour in the space’s timezone. The digest payload uses the space.digest event type:
{
  "type": "space.digest",
  "projectId": "your-project-id",
  "spaceId": "the-space-id",
  "data": { ... }
}
The data object contains the assembled digest — new entities, new members, and summary counts for the period. Configuration is per space (not per project). Each space has:
  • digestEnabled — whether the digest is active
  • digestWebhookUrl — where to POST the digest
  • digestWebhookSecret — used for HMAC-SHA256 signing (same mechanism as project webhooks)
  • digestScheduleHour — the hour of day to send (0–23)
  • digestTimezone — the timezone for the schedule
Space digests are available on Pro and Growth plans only. If there is no new activity in the 24-hour window, the digest is skipped for that day.
The digest webhook is the hook point for forwarding summaries to an email provider, Slack, or any other notification channel for space members.