Skip to content
V2 (Legacy) API ReferenceGet started

Webhook Events

Webhook Subscriptions allow you to receive real-time notifications when events occur on your account.

Configure webhook endpoints to receive events such as messages sent/received, delivery status changes, reactions, typing indicators, and more.

Failed deliveries (5xx, 429, network errors) are retried up to 10 times over ~25 minutes with exponential backoff. Each event includes a unique ID for deduplication.

Webhook Headers

Each webhook request includes the following headers:

HeaderDescription
X-Webhook-EventThe event type (e.g., message.sent, message.received)
X-Webhook-Subscription-IDYour webhook subscription ID
X-Webhook-TimestampUnix timestamp (seconds) when the webhook was sent
X-Webhook-SignatureHMAC-SHA256 signature for verification

Verifying Webhook Signatures

All webhooks are signed using HMAC-SHA256. You should always verify the signature to ensure the webhook originated from Linq and hasn’t been tampered with.

Signature Construction:

The signature is computed over a concatenation of the timestamp and payload:

{timestamp}.{payload}

Where:

  • timestamp is the value from the X-Webhook-Timestamp header
  • payload is the raw JSON request body (exact bytes, not re-serialized)

Verification Steps:

  1. Extract the X-Webhook-Timestamp and X-Webhook-Signature headers
  2. Get the raw request body bytes (do not parse and re-serialize)
  3. Concatenate: "{timestamp}.{payload}"
  4. Compute HMAC-SHA256 using your signing secret as the key
  5. Hex-encode the result and compare with X-Webhook-Signature
  6. Use constant-time comparison to prevent timing attacks

Example (Python):

import hmac
import hashlib

def verify_webhook(signing_secret, payload, timestamp, signature):
    message = f"{timestamp}.{payload.decode('utf-8')}"
    expected = hmac.new(
        signing_secret.encode('utf-8'),
        message.encode('utf-8'),
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, signature)

Example (Node.js):

const crypto = require('crypto');

function verifyWebhook(signingSecret, payload, timestamp, signature) {
  const message = `${timestamp}.${payload}`;
  const expected = crypto
    .createHmac('sha256', signingSecret)
    .update(message)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signature)
  );
}

Security Best Practices:

  • Reject webhooks with timestamps older than 5 minutes to prevent replay attacks
  • Always use constant-time comparison for signature verification
  • Store your signing secret securely (e.g., environment variable, secrets manager)
  • Return a 2xx status code quickly, then process the webhook asynchronously
List available webhook event types
client.WebhookEvents.List(ctx) (*WebhookEventListResponse, error)
GET/v3/webhook-events
ModelsExpand Collapse
type WebhookEventType string

Valid webhook event types that can be subscribed to.

Note: message.edited is only delivered to subscriptions using webhook_version: "2026-02-03". Subscribing to this event on a v2025 subscription will not produce any deliveries.

One of the following:
const WebhookEventTypeMessageSent WebhookEventType = "message.sent"
const WebhookEventTypeMessageReceived WebhookEventType = "message.received"
const WebhookEventTypeMessageRead WebhookEventType = "message.read"
const WebhookEventTypeMessageDelivered WebhookEventType = "message.delivered"
const WebhookEventTypeMessageFailed WebhookEventType = "message.failed"
const WebhookEventTypeMessageEdited WebhookEventType = "message.edited"
const WebhookEventTypeReactionAdded WebhookEventType = "reaction.added"
const WebhookEventTypeReactionRemoved WebhookEventType = "reaction.removed"
const WebhookEventTypeParticipantAdded WebhookEventType = "participant.added"
const WebhookEventTypeParticipantRemoved WebhookEventType = "participant.removed"
const WebhookEventTypeChatCreated WebhookEventType = "chat.created"
const WebhookEventTypeChatGroupNameUpdated WebhookEventType = "chat.group_name_updated"
const WebhookEventTypeChatGroupIconUpdated WebhookEventType = "chat.group_icon_updated"
const WebhookEventTypeChatGroupNameUpdateFailed WebhookEventType = "chat.group_name_update_failed"
const WebhookEventTypeChatGroupIconUpdateFailed WebhookEventType = "chat.group_icon_update_failed"
const WebhookEventTypeChatTypingIndicatorStarted WebhookEventType = "chat.typing_indicator.started"
const WebhookEventTypeChatTypingIndicatorStopped WebhookEventType = "chat.typing_indicator.stopped"
const WebhookEventTypePhoneNumberStatusUpdated WebhookEventType = "phone_number.status_updated"
const WebhookEventTypeCallInitiated WebhookEventType = "call.initiated"
const WebhookEventTypeCallRinging WebhookEventType = "call.ringing"
const WebhookEventTypeCallAnswered WebhookEventType = "call.answered"
const WebhookEventTypeCallEnded WebhookEventType = "call.ended"
const WebhookEventTypeCallFailed WebhookEventType = "call.failed"
const WebhookEventTypeCallDeclined WebhookEventType = "call.declined"
const WebhookEventTypeCallNoAnswer WebhookEventType = "call.no_answer"