On this page

Webhooks

ScaliQ can POST JSON to your HTTPS URL when events occur.

Setup

  1. Open app.scaliq.ai/api-mcp → Webhooks
  2. Create a subscription: name, HTTPS URL, events, optional campaign filter
  3. Optionally set a signing secret (you choose the string)

Default max 5 webhooks per workspace. Manage subscriptions in the dashboard (not via REST in v1).

Events

EventWhen
reply.receivedProspect replied
connection.acceptedConnection accepted
lead.taggedLead tagged (manual or auto)
account.disconnectedLinkedIn account disconnected / failed

Events are delivered when ScaliQ records them — typically soon after they happen on LinkedIn.

data.accountId is the LinkedIn account for the lead when known. For lead.tagged, if the lead has no stored account, ScaliQ falls back to the inbox chat’s account. May still be null if there is no chat yet.

Payload shape

{
  "id": "evt_...",
  "type": "reply.received",
  "createdAt": "2026-07-24T05:00:00.000Z",
  "data": {
    "campaignId": "search_abc",
    "leadId": "lead_xyz",
    "accountId": "acc_...",
    "linkedinUrl": "https://www.linkedin.com/in/jane-doe/",
    "fullName": "Jane Doe",
    "messageText": "Thanks, interested in learning more.",
    "tag": null,
    "messageId": "msg_...",
    "conversationId": "acc_...__ACoAA...",
    "messageTimestamp": "2026-07-24T04:59:58.000Z",
    "direction": "incoming"
  }
}

data fields present depend on the event (messageText / message ids on replies; tag on tag events; etc.). messageText may be truncated (~4000 chars).

On reply.received, use messageId + messageTimestamp for incremental sync and duplicate prevention. conversationId is ScaliQ’s thread id when available. direction is "incoming". Envelope createdAt is webhook delivery time; messageTimestamp is when ScaliQ recorded the inbound message. Other events include the same keys as null.

connection.accepted (example)

{
  "id": "evt_...",
  "type": "connection.accepted",
  "createdAt": "2026-07-24T05:00:00.000Z",
  "data": {
    "campaignId": "search_abc",
    "leadId": "lead_xyz",
    "accountId": "acc_...",
    "linkedinUrl": "https://www.linkedin.com/in/jane-doe/",
    "fullName": "Jane Doe",
    "messageText": null,
    "tag": null,
    "messageId": null,
    "conversationId": null,
    "messageTimestamp": null,
    "direction": null
  }
}

lead.tagged (example)

{
  "id": "evt_...",
  "type": "lead.tagged",
  "createdAt": "2026-07-24T05:00:00.000Z",
  "data": {
    "campaignId": "search_abc",
    "leadId": "lead_xyz",
    "accountId": "acc_...",
    "linkedinUrl": "https://www.linkedin.com/in/jane-doe/",
    "fullName": "Jane Doe",
    "messageText": null,
    "tag": "Interested",
    "messageId": null,
    "conversationId": null,
    "messageTimestamp": null,
    "direction": null
  }
}

account.disconnected (example)

{
  "id": "evt_...",
  "type": "account.disconnected",
  "createdAt": "2026-07-24T05:00:00.000Z",
  "data": {
    "campaignId": null,
    "leadId": null,
    "accountId": "acc_...",
    "linkedinUrl": null,
    "fullName": null,
    "messageText": null,
    "tag": null,
    "messageId": null,
    "conversationId": null,
    "messageTimestamp": null,
    "direction": null
  }
}

Signing (optional)

When you set a signing secret in app.scaliq.ai/api-mcp, every delivery includes:

X-Webhook-Signature: <your-secret>
X-ScaliQ-Signature: <your-secret>

The value is exactly the string you entered (e.g. password1234) — not an HMAC, not sha256=<hex>.

n8n: Header Auth → header X-Webhook-Signature, value = that same secret.
(X-ScaliQ-Signature carries the same value and keeps working for existing setups — prefer X-Webhook-Signature for new integrations.)

If no secret is set → deliveries are unsigned (no signature headers).

See verify webhook signature.

Delivery

  • Up to 3 attempts with backoff
  • At-most-once (not guaranteed if the worker dies mid-flight)
  • Failures never block ScaliQ inbox / tagging flows