Skip to main content

Setup

Configure webhooks in the Dashboard or via the API. Each webhook endpoint receives events as HTTP POST requests with a JSON body.
1

Register your endpoint URL

Provide an HTTPS URL that can receive POST requests. The URL must return a 2xx status code within 30 seconds.
2

Select event types

Choose which event types to subscribe to. You can subscribe to all events or specific types.
3

Store your signing secret

Synap generates an HMAC signing secret for your endpoint. Store it securely — you will need it to verify webhook signatures.
4

Verify signatures in your handler

Every webhook request includes a signature header. Verify it before processing the payload.

Signature Verification

Every webhook request includes an X-Synap-Signature header containing an HMAC-SHA256 signature of the request body. Always verify this signature to ensure the request is authentic. The signature is computed as:
HMAC-SHA256(signing_secret, raw_request_body)

Verification Examples

import hmac
import hashlib

def verify_webhook(request_body: bytes, signature: str, signing_secret: str) -> bool:
    expected = hmac.new(
        signing_secret.encode("utf-8"),
        request_body,
        hashlib.sha256,
    ).hexdigest()
    return hmac.compare_digest(f"sha256={expected}", signature)

# In your webhook handler:
# body = await request.body()
# signature = request.headers["X-Synap-Signature"]
# if not verify_webhook(body, signature, SIGNING_SECRET):
#     return Response(status_code=401)
Always use constant-time comparison (e.g., hmac.compare_digest in Python, crypto.timingSafeEqual in Node.js) to prevent timing attacks when verifying signatures.

Delivery Behavior

Retry Policy

If your endpoint returns a non-2xx status code or does not respond within 30 seconds, Synap retries delivery with exponential backoff:
AttemptDelay
1st retry1 minute
2nd retry5 minutes
3rd retry30 minutes
4th retry2 hours
5th retry12 hours
After 5 failed attempts, the event is marked as failed and no further retries are attempted. Failed events are visible in the Dashboard webhook logs for 30 days.

Delivery Statuses

StatusDescription
pendingEvent is queued for delivery
deliveredEndpoint returned a 2xx response
retryingDelivery failed, retrying with backoff
failedAll retry attempts exhausted

Ordering

Webhook events are delivered in approximate chronological order but not guaranteed to be strictly ordered. Use the timestamp field in the payload to determine the actual event sequence.

Idempotency

Each event has a unique event_id. Your handler should be idempotent — the same event may be delivered more than once in rare cases (e.g., network timeouts where the response was lost).

Common Headers

Every webhook request includes these headers:
HeaderDescription
Content-TypeAlways application/json
X-Synap-SignatureHMAC-SHA256 signature of the request body
X-Synap-EventThe event type (e.g., conversation.started)
X-Synap-Delivery-IdUnique delivery attempt ID
X-Synap-TimestampISO 8601 timestamp of when the event was sent
User-AgentSynap-Webhooks/1.0

Event Types

conversation.started

Fired when a new conversation is initiated with the SDK.
{
  "event_id": "evt_1a2b3c4d5e6f7890",
  "event_type": "conversation.started",
  "timestamp": "2025-01-15T10:00:00Z",
  "instance_id": "inst_f1e2d3c4b5a69078",
  "data": {
    "conversation_id": "conv_abc123",
    "user_id": "user_789",
    "customer_id": "cust_456",
    "metadata": {
      "source": "web-chat",
      "session_id": "sess_xyz"
    },
    "started_at": "2025-01-15T10:00:00Z"
  }
}

conversation.ended

Fired when a conversation is explicitly ended or times out.
{
  "event_id": "evt_2b3c4d5e6f7a8901",
  "event_type": "conversation.ended",
  "timestamp": "2025-01-15T11:30:00Z",
  "instance_id": "inst_f1e2d3c4b5a69078",
  "data": {
    "conversation_id": "conv_abc123",
    "user_id": "user_789",
    "customer_id": "cust_456",
    "reason": "user_ended",
    "duration_seconds": 5400,
    "message_count": 24,
    "memories_created": 7,
    "ended_at": "2025-01-15T11:30:00Z"
  }
}

context.retrieved

Fired when context is fetched for a conversation.
{
  "event_id": "evt_3c4d5e6f7a8b9012",
  "event_type": "context.retrieved",
  "timestamp": "2025-01-15T10:05:00Z",
  "instance_id": "inst_f1e2d3c4b5a69078",
  "data": {
    "conversation_id": "conv_abc123",
    "user_id": "user_789",
    "mode": "balanced",
    "results_count": 5,
    "query_time_ms": 47,
    "tokens_used": 312,
    "memory_types_returned": ["fact", "preference"],
    "search_queries": ["coffee preferences", "location"]
  }
}

config.applied

Fired when a memory architecture configuration is applied to an instance.
{
  "event_id": "evt_4d5e6f7a8b9c0123",
  "event_type": "config.applied",
  "timestamp": "2025-01-15T17:00:00Z",
  "instance_id": "inst_f1e2d3c4b5a69078",
  "data": {
    "config_id": "maca_cfg_5e6f7a8b",
    "version": 2,
    "applied_by": "user_admin_001",
    "mode": "graceful",
    "previous_config_id": "maca_cfg_1a2b3c4d",
    "previous_version": 1,
    "changes_summary": {
      "retrieval.context_budget": {
        "from": 4096,
        "to": 8192
      },
      "retrieval.mode": {
        "from": "balanced",
        "to": "accurate"
      }
    },
    "applied_at": "2025-01-15T17:00:00Z"
  }
}

compaction.completed

Fired when a context compaction completes successfully.
{
  "event_id": "evt_5e6f7a8b9c0d1234",
  "event_type": "compaction.completed",
  "timestamp": "2025-01-15T16:00:05Z",
  "instance_id": "inst_f1e2d3c4b5a69078",
  "data": {
    "compaction_id": "cmp_1a2b3c4d5e6f7890",
    "conversation_id": "conv_abc123",
    "user_id": "user_789",
    "strategy": "summarize",
    "version": 1,
    "tokens_before": 2847,
    "tokens_after": 487,
    "compression_ratio": 5.8,
    "validation_score": 0.94,
    "processing_time_ms": 3200,
    "completed_at": "2025-01-15T16:00:05Z"
  }
}

Testing Webhooks

Use the Dashboard webhook testing tool to send test events to your endpoint. Navigate to Settings > Webhooks > Test and select an event type.

Best Practices

Respond quickly

Return a 2xx response as soon as possible. Process the webhook payload asynchronously in a background job rather than doing heavy work in the handler.

Handle duplicates

Use the event_id to deduplicate events. Store processed event IDs and skip any you have already handled.

Verify signatures

Always verify the X-Synap-Signature header. Reject requests with invalid signatures to prevent spoofing.

Use HTTPS

Webhook endpoints must use HTTPS. Synap does not deliver events to plaintext HTTP endpoints.