Documentation

Webhooks

Receive every event at your own URL as it happens.

Adding a webhook

Add one in Settings, with Create a webhook, or with the needleCreateWebhook MCP tool. Any member of the workspace can add webhooks. Only the member who added a webhook can change it; they or a workspace admin can delete it. A workspace can have up to 5, and each one gets every event type the member who created it can see. When that member leaves the workspace, their webhooks are deleted.

The URL must start with https://. When you add a webhook you get its signing secret, which starts with whsec_. It is shown only this once, so store it where your receiver can read it.

What Needle sends

Each event is one POST with a JSON body:

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "linkedin_message_received",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "linkedin_message_received",
    "label": "Reply received",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": "linkedin",
    "nodeId": null,
    "leadId": "00000000-0000-0000-0000-000000000002",
    "leadName": "Jane Doe",
    "leadImageUrl": null,
    "campaignId": "00000000-0000-0000-0000-000000000003",
    "campaignName": "Example campaign",
    "enrollmentId": "00000000-0000-0000-0000-000000000004",
    "connectedAccountId": "00000000-0000-0000-0000-000000000005",
    "accountName": "John Doe",
    "data": { "text": "Hello!" }
  }
}

data is the same event object that Search events returns. timestamp is when the event happened. The event's own data field depends on its type; see Event types.

Each request also has these headers:

  • webhook-id: the event id. It stays the same when a request is sent again.
  • webhook-timestamp: when this request was sent, in Unix seconds.
  • webhook-signature: v1, followed by a base64 HMAC-SHA256 of {webhook-id}.{webhook-timestamp}.{body}, keyed with your secret.

Verifying requests

The headers follow Standard Webhooks, so its libraries can check them. A request that fails the check did not come from Needle. The libraries also refuse a request whose webhook-timestamp is more than 5 minutes from your server's clock, so a captured request can't be sent again later.

Verify a request

Pass the raw body, before any JSON parsing, and the request headers to verify().

$ npm install express standardwebhooks
import express from 'express'
import { Webhook } from 'standardwebhooks'

const webhook = new Webhook(process.env.NEEDLE_WEBHOOK_SECRET)
const app = express()

app.post('/webhooks/needle', express.raw({ type: 'application/json' }), (req, res) => {
  let event
  try {
    event = webhook.verify(req.body, req.headers)
  } catch {
    return res.status(400).end()
  }
  res.status(204).end()
  // Handle the event here, after answering.
})

Standard Webhooks has libraries for other languages.

Custom headers

If your endpoint requires its own key, such as Authorization: Bearer <your key>, add it as a header in Settings, or with headers in Create a webhook or Update a webhook. Needle sends it with every request.

  • A webhook can have up to 5 headers. Names are stored in lower case.
  • To change one header, send only its new value; the others stay as they are. To remove one, send null.
  • Needle's own headers can't be replaced: content-type, content-encoding, user-agent, the webhook- headers, and connection headers such as host.
  • Changing the URL removes the saved headers, so a key never follows the webhook to a new address. Add them again in the same change.

Headers are not part of the signature, so verifying requests works the same way.

Retries

An event fails when your URL doesn't answer with a 2xx within 10 seconds. A failed event is tried 3 times: right away, 10 minutes later, and 1 hour after the first try. After the 3rd failure it is not sent again. An event that has not been delivered after 3 days is given up without further tries.

If your URL answers 429, we stop sending to it for a few seconds. The events that got the 429 are tried again on the schedule above.

Missed events are still in the event log. Fetch them with Search events.

Duplicates and order

Delivery is at least once: after a crash on our side, an event you already got can arrive again. Use webhook-id to skip events you have already handled.

Events are not sent in order: up to 5 requests to your URL can be open at once, and a retried event can arrive after newer ones. Use timestamp for the order in which things happened.

Changing or deleting a webhook

Change the URL or the headers in Settings, or with Update a webhook. Events not yet delivered go out with the new URL and headers, and the secret stays the same.

Deleting a webhook stops its deliveries, and events not yet delivered to it are dropped. If you lose the secret, delete the webhook and add it again to get a new one.

Event types

Search events, the MCP tools, and webhooks all use the same event object. nodeId is the campaign step, enrollmentId is the lead's run through a campaign, and label is the name the app shows for the type. What data holds depends on type.

To match a lead in your own system, fetch it by leadId with Get a lead: it returns the lead's email (when known) and its LinkedIn and Instagram identities.

TypeWhen it is sent
lead_createdA lead was created, from the app, the API, MCP, an import, or a direct message to someone who was not a lead yet.
lead_updatedA lead's details or handles changed; data.changes lists each changed field.
lead_deletedA lead was deleted. Its live campaigns stop with exitReason lead_deleted.
lead_enrolledA lead was added to a campaign.
lead_skippedA lead was not added to a campaign; data.skipReason says why.
message_generatedAI wrote a message for a step.
condition_evaluatedA check in the sequence was evaluated.
task_heldA step is waiting for approval.
task_approvedA held step was approved.
task_skippedA step was skipped; data.skipReason says why.
task_cancelledA step was cancelled before it ran.
task_failedA step failed; data.errorKind says why.
enrollment_waitingThe sequence is waiting, for example for a reply.
enrollment_completedThe lead reached the end of the sequence.
enrollment_stoppedThe sequence stopped early; data.exitReason says why.
lead_suppressedA lead matched a suppression.
campaign_status_changedA campaign's status changed, for example it was started or paused.
campaign_updatedA campaign's name, sequence, schedule, limits or suppression policy was edited; data.changedFields lists which.
account_connectedA LinkedIn or Instagram account was connected to the workspace for the first time, or again after it was deleted.
account_reconnectedA disconnected account works again, because a member signed in to it again or LinkedIn or Instagram reports it healthy.
account_deletedA connected account was deleted.
account_pausedA connected account was paused, by its owner or after hitting a limit (data.errorKind).
account_resumedA paused connected account was resumed, by its owner or when billing was restored.
account_disconnectedA connected account stopped working: it needs signing in again (data.errorKind is auth_required) or LinkedIn or Instagram disconnected it (disconnected). Its campaigns wait until it is reconnected.
account_suspendedA connected account was signed out and stopped, because the workspace's billing lapsed or its owner was removed from the workspace (data.message). It has to be connected again to be used.
account_limits_updatedA connected account's usage limits were changed; data.changes lists each limit.
account_access_grantedA member (data.member) was allowed to use a connected account.
account_access_revokedA member (data.member) can no longer use a connected account. Campaigns they started with it pause.
account_sharing_changedA connected account was shared with the whole workspace, or stopped being shared.
member_invitedSomeone was invited to the workspace.
member_invitation_revokedAn invitation to the workspace was withdrawn.
member_joinedSomeone accepted an invitation and joined.
member_role_changedA member's role changed.
member_removedAn admin removed a member. Their accounts are suspended and their campaigns pause.
member_leftA member deleted their Needle account.
api_key_createdAn API key was created.
api_key_revokedAn API key was disabled.
api_key_enabledA disabled API key was enabled again.
api_key_deletedAn API key was deleted.
webhook_createdA webhook was added.
webhook_updatedA webhook's URL or headers changed; data.changedFields lists which.
webhook_deletedA webhook was removed.
suppression_addedA lead or company was added to the do-not-contact list by a member or through the API.
suppression_removedAn entry was removed from the do-not-contact list.
linkedin_profile_visitedA LinkedIn profile was visited.
linkedin_invite_sentA LinkedIn connection request was sent.
linkedin_invite_withdrawnA LinkedIn connection request was withdrawn.
linkedin_message_sentA LinkedIn message was sent, through Needle or by the account owner in LinkedIn (data.sentOutsideNeedle).
linkedin_follow_sentA LinkedIn profile was followed.
linkedin_unfollowedA LinkedIn profile was unfollowed.
linkedin_invite_acceptedA LinkedIn connection request was accepted.
linkedin_message_receivedA LinkedIn reply was received.
linkedin_post_commentedA comment was posted on LinkedIn.
linkedin_post_reactedA reaction was added to a LinkedIn post.
instagram_message_sentAn Instagram message was sent, through Needle or by the account owner in Instagram (data.sentOutsideNeedle).
instagram_profile_visitedAn Instagram profile was visited.
instagram_follow_sentAn Instagram profile was followed.
instagram_unfollowedAn Instagram profile was unfollowed.
instagram_message_receivedAn Instagram reply was received.
instagram_post_commentedA comment was posted on Instagram.
instagram_post_reactedAn Instagram post was liked.
instagram_message_reactedA reaction was added to an Instagram message.
instagram_post_createdAn Instagram post was published.

Who sees an event

What a connected account says or does on LinkedIn or Instagram is account-sensitive: linkedin_profile_visited, linkedin_invite_sent, linkedin_invite_withdrawn, linkedin_message_sent, linkedin_follow_sent, linkedin_unfollowed, linkedin_invite_accepted, linkedin_message_received, linkedin_post_commented, linkedin_post_reacted, instagram_message_sent, instagram_profile_visited, instagram_follow_sent, instagram_unfollowed, instagram_message_received, instagram_post_commented, instagram_post_reacted, instagram_message_reacted, instagram_post_created.

  • An event that is not account-sensitive is visible to everyone in the workspace, for example task_held, account_connected, or member_invited.
  • An account-sensitive event about one of your leads is visible to users with access to the account: its owner, members it is shared with, or everyone when it is shared with the workspace.
  • An account-sensitive event not about one of your leads, such as a message to someone outside your leads, is visible only to the account's owner.

Search events and the MCP tools follow these rules for whoever calls them. A webhook receives what the member who created it can see, and is deleted when that member leaves the workspace. For everything else access covers, see Who can do what.

Fields in data

FieldMeaning
actionThe action Needle took. One of: linkedin_invitation, linkedin_cancel_invitation, linkedin_message, linkedin_inmail, linkedin_profile_view, linkedin_comment, linkedin_reaction, instagram_message, instagram_profile_view, instagram_follow, instagram_unfollow, instagram_comment, instagram_reaction, instagram_post.
textThe text sent, received, or written by AI: a message, connection note, comment, or caption.
subjectThe subject line of an InMail.
messageA short note from Needle, for example why a step was cancelled or a status change such as draft -> active.
skipReasonWhy the lead or step was skipped. One of: duplicate_in_batch, enrolled_elsewhere, suppressed, recently_contacted, unresponsive, daily_limit_reached, lead_not_found, missing_identity, missing_personalization, already_connected, already_invited, already_following, follow_request_pending, not_first_degree, invalid_recipient, generation_failed.
exitReasonWhy the sequence ended. One of: finished, replied, messaged_directly, timeout, manual, suppressed, dead_end, error, account_disconnected, campaign_archived, lead_deleted.
suppressionReasonWhich kind of suppression matched. One of: manual, unsubscribed, not_interested, existing_customer, open_opportunity, competitor, employee, invalid_recipient, complained, recently_contacted, unresponsive.
keywordThe opt-out phrase found in the reply, for example unsubscribe.
errorKindA short error code, for example rate_limited, auth_required, or invalid_recipient. New codes can appear.
profileAn object about the person: who the action was aimed at, or who replied or accepted. It has name, identity (the LinkedIn public identifier or Instagram username, or the user id when there is none), url, and imageUrl. All but identity can be null.
changesAn object keyed by changed field, each { "from": ..., "to": ... } with string or null values. On lead_updated the keys are the lead fields (firstName, lastName, companyName, companyDomain, jobTitle, email, timezone), the handles (linkedin, instagram), and properties.<key> for custom properties. On account_limits_updated they are `<action>.<hour
changedFieldsThe fields that changed when their values are too large or too secret to include: name, graph, schedule, limits, suppressionPolicy for a campaign, url and headers for a webhook.
memberThe workspace member the event is about, as { "userId": ..., "name": ... }. actorUserId is who made the change.
emailThe email address an invitation was sent to.
roleThe workspace role: member, admin, or owner.
apiKeyThe API key the event is about, as { "id": ..., "name": ... }. The key itself is never included.
webhookThe webhook the event is about, as { "id": ..., "host": ... }. Only the URL's host is included, since URLs can hold tokens.
suppressionIdThe do-not-contact entry the event is about.
companyDomainThe company domain a do-not-contact entry covers.
propertiesAn object of strings, with the keys listed under each type below: branch (yes or no), edited (true or false), waitingFor (the event the sequence waits for), timeoutAt and pausedUntil (ISO 8601 times).

Each event type

Set lists which of leadId, campaignId, enrollmentId, connectedAccountId, channel, and nodeId the type fills in; the others are null. leadName, campaignName, and accountName follow their ids. In data, a field marked ? is only on some events of that type, and a field not listed is missing or null. The examples are full request bodies, like the one in What Needle sends, with made-up values.

lead_created

A lead was created, from the app, the API, MCP, an import, or a direct message to someone who was not a lead yet.

Set: leadId.

data: profile?

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "lead_created",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "lead_created",
    "label": "Lead created",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": null,
    "nodeId": null,
    "leadId": "00000000-0000-0000-0000-000000000002",
    "leadName": "Jane Doe",
    "leadImageUrl": null,
    "campaignId": null,
    "campaignName": null,
    "enrollmentId": null,
    "connectedAccountId": null,
    "accountName": null,
    "actorUserId": null,
    "actorName": null,
    "data": {
      "profile": {
        "name": "Jane Doe",
        "identity": "jane-doe",
        "url": "https://www.linkedin.com/in/jane-doe"
      }
    }
  }
}

lead_updated

A lead's details or handles changed; data.changes lists each changed field.

Set: leadId.

data: changes

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "lead_updated",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "lead_updated",
    "label": "Lead updated",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": null,
    "nodeId": null,
    "leadId": "00000000-0000-0000-0000-000000000002",
    "leadName": "Jane Doe",
    "leadImageUrl": null,
    "campaignId": null,
    "campaignName": null,
    "enrollmentId": null,
    "connectedAccountId": null,
    "accountName": null,
    "actorUserId": null,
    "actorName": null,
    "data": {
      "changes": {
        "jobTitle": {
          "from": "Engineer",
          "to": "Head of Engineering"
        },
        "linkedin": {
          "from": null,
          "to": "jane-doe"
        }
      }
    }
  }
}

lead_deleted

A lead was deleted. Its live campaigns stop with exitReason lead_deleted.

Set: leadId.

data: profile?

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "lead_deleted",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "lead_deleted",
    "label": "Lead deleted",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": null,
    "nodeId": null,
    "leadId": "00000000-0000-0000-0000-000000000002",
    "leadName": "Jane Doe",
    "leadImageUrl": null,
    "campaignId": null,
    "campaignName": null,
    "enrollmentId": null,
    "connectedAccountId": null,
    "accountName": null,
    "actorUserId": null,
    "actorName": null,
    "data": {
      "profile": {
        "name": "Jane Doe",
        "identity": "jane-doe",
        "url": "https://www.linkedin.com/in/jane-doe"
      }
    }
  }
}

lead_enrolled

A lead was added to a campaign.

Set: leadId, campaignId, enrollmentId.

data: null

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "lead_enrolled",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "lead_enrolled",
    "label": "Lead added",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": null,
    "nodeId": null,
    "leadId": "00000000-0000-0000-0000-000000000002",
    "leadName": "Jane Doe",
    "leadImageUrl": null,
    "campaignId": "00000000-0000-0000-0000-000000000003",
    "campaignName": "Example campaign",
    "enrollmentId": "00000000-0000-0000-0000-000000000004",
    "connectedAccountId": null,
    "accountName": null,
    "actorUserId": null,
    "actorName": null,
    "data": null
  }
}

lead_skipped

A lead was not added to a campaign; data.skipReason says why.

Set: leadId, campaignId. leadId is null when skipReason is lead_not_found.

data: skipReason, message?

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "lead_skipped",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "lead_skipped",
    "label": "Lead skipped",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": null,
    "nodeId": null,
    "leadId": "00000000-0000-0000-0000-000000000002",
    "leadName": "Jane Doe",
    "leadImageUrl": null,
    "campaignId": "00000000-0000-0000-0000-000000000003",
    "campaignName": "Example campaign",
    "enrollmentId": null,
    "connectedAccountId": null,
    "accountName": null,
    "actorUserId": null,
    "actorName": null,
    "data": {
      "skipReason": "recently_contacted",
      "message": "Contacted by your workspace within the last 30 days"
    }
  }
}

message_generated

AI wrote a message for a step.

Set: leadId, campaignId, enrollmentId, connectedAccountId, channel, nodeId.

data: text

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "message_generated",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "message_generated",
    "label": "AI message written",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": "linkedin",
    "nodeId": "step_1",
    "leadId": "00000000-0000-0000-0000-000000000002",
    "leadName": "Jane Doe",
    "leadImageUrl": null,
    "campaignId": "00000000-0000-0000-0000-000000000003",
    "campaignName": "Example campaign",
    "enrollmentId": "00000000-0000-0000-0000-000000000004",
    "connectedAccountId": "00000000-0000-0000-0000-000000000005",
    "accountName": "John Doe",
    "actorUserId": null,
    "actorName": null,
    "data": {
      "text": "Hi Jane, open to a quick chat?"
    }
  }
}

condition_evaluated

A check in the sequence was evaluated.

Set: leadId, campaignId, enrollmentId, connectedAccountId, channel, nodeId.

data: action, properties.branch, message?

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "condition_evaluated",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "condition_evaluated",
    "label": "Check evaluated",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": "linkedin",
    "nodeId": "step_1",
    "leadId": "00000000-0000-0000-0000-000000000002",
    "leadName": "Jane Doe",
    "leadImageUrl": null,
    "campaignId": "00000000-0000-0000-0000-000000000003",
    "campaignName": "Example campaign",
    "enrollmentId": "00000000-0000-0000-0000-000000000004",
    "connectedAccountId": "00000000-0000-0000-0000-000000000005",
    "accountName": "John Doe",
    "actorUserId": null,
    "actorName": null,
    "data": {
      "action": "linkedin_profile_view",
      "properties": {
        "branch": "no"
      }
    }
  }
}

task_held

A step is waiting for approval.

Set: leadId, campaignId, enrollmentId, connectedAccountId, channel, nodeId.

data: action, text, subject?

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "task_held",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "task_held",
    "label": "Held for approval",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": "linkedin",
    "nodeId": "step_1",
    "leadId": "00000000-0000-0000-0000-000000000002",
    "leadName": "Jane Doe",
    "leadImageUrl": null,
    "campaignId": "00000000-0000-0000-0000-000000000003",
    "campaignName": "Example campaign",
    "enrollmentId": "00000000-0000-0000-0000-000000000004",
    "connectedAccountId": "00000000-0000-0000-0000-000000000005",
    "accountName": "John Doe",
    "actorUserId": null,
    "actorName": null,
    "data": {
      "action": "linkedin_message",
      "text": "Hi Jane, open to a quick chat?",
      "subject": null
    }
  }
}

task_approved

A held step was approved.

Set: leadId, campaignId, enrollmentId, connectedAccountId, channel, nodeId.

data: action, text, properties.edited

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "task_approved",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "task_approved",
    "label": "Message approved",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": "linkedin",
    "nodeId": "step_1",
    "leadId": "00000000-0000-0000-0000-000000000002",
    "leadName": "Jane Doe",
    "leadImageUrl": null,
    "campaignId": "00000000-0000-0000-0000-000000000003",
    "campaignName": "Example campaign",
    "enrollmentId": "00000000-0000-0000-0000-000000000004",
    "connectedAccountId": "00000000-0000-0000-0000-000000000005",
    "accountName": "John Doe",
    "actorUserId": null,
    "actorName": null,
    "data": {
      "action": "linkedin_message",
      "text": "Hi Jane, open to a quick chat?",
      "properties": {
        "edited": "true"
      }
    }
  }
}

task_skipped

A step was skipped; data.skipReason says why.

Set: leadId, campaignId, enrollmentId, connectedAccountId, channel, nodeId.

data: action, skipReason

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "task_skipped",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "task_skipped",
    "label": "Step skipped",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": "linkedin",
    "nodeId": "step_1",
    "leadId": "00000000-0000-0000-0000-000000000002",
    "leadName": "Jane Doe",
    "leadImageUrl": null,
    "campaignId": "00000000-0000-0000-0000-000000000003",
    "campaignName": "Example campaign",
    "enrollmentId": "00000000-0000-0000-0000-000000000004",
    "connectedAccountId": "00000000-0000-0000-0000-000000000005",
    "accountName": "John Doe",
    "actorUserId": null,
    "actorName": null,
    "data": {
      "action": "linkedin_invitation",
      "skipReason": "already_invited"
    }
  }
}

task_cancelled

A step was cancelled before it ran.

Set: leadId, campaignId, enrollmentId, connectedAccountId, channel, nodeId.

data: action, message

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "task_cancelled",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "task_cancelled",
    "label": "Step cancelled",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": "linkedin",
    "nodeId": "step_1",
    "leadId": "00000000-0000-0000-0000-000000000002",
    "leadName": "Jane Doe",
    "leadImageUrl": null,
    "campaignId": "00000000-0000-0000-0000-000000000003",
    "campaignName": "Example campaign",
    "enrollmentId": "00000000-0000-0000-0000-000000000004",
    "connectedAccountId": "00000000-0000-0000-0000-000000000005",
    "accountName": "John Doe",
    "actorUserId": null,
    "actorName": null,
    "data": {
      "action": "linkedin_message",
      "message": "The lead is no longer active in this campaign (stopped)"
    }
  }
}

task_failed

A step failed; data.errorKind says why.

Set: leadId, campaignId, enrollmentId, connectedAccountId, channel, nodeId.

data: action, skipReason?, errorKind?, message?

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "task_failed",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "task_failed",
    "label": "Step failed",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": "linkedin",
    "nodeId": "step_1",
    "leadId": "00000000-0000-0000-0000-000000000002",
    "leadName": "Jane Doe",
    "leadImageUrl": null,
    "campaignId": "00000000-0000-0000-0000-000000000003",
    "campaignName": "Example campaign",
    "enrollmentId": "00000000-0000-0000-0000-000000000004",
    "connectedAccountId": "00000000-0000-0000-0000-000000000005",
    "accountName": "John Doe",
    "actorUserId": null,
    "actorName": null,
    "data": {
      "action": "linkedin_message",
      "skipReason": "not_first_degree"
    }
  }
}

enrollment_waiting

The sequence is waiting, for example for a reply.

Set: leadId, campaignId, enrollmentId, channel, nodeId.

data: properties.waitingFor, properties.timeoutAt

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "enrollment_waiting",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "enrollment_waiting",
    "label": "Sequence waiting",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": "linkedin",
    "nodeId": "step_1",
    "leadId": "00000000-0000-0000-0000-000000000002",
    "leadName": "Jane Doe",
    "leadImageUrl": null,
    "campaignId": "00000000-0000-0000-0000-000000000003",
    "campaignName": "Example campaign",
    "enrollmentId": "00000000-0000-0000-0000-000000000004",
    "connectedAccountId": null,
    "accountName": null,
    "actorUserId": null,
    "actorName": null,
    "data": {
      "properties": {
        "waitingFor": "linkedin_invite_accepted",
        "timeoutAt": "2026-01-15T12:00:00.000Z"
      }
    }
  }
}

enrollment_completed

The lead reached the end of the sequence.

Set: leadId, campaignId, enrollmentId.

data: exitReason

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "enrollment_completed",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "enrollment_completed",
    "label": "Sequence finished",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": null,
    "nodeId": null,
    "leadId": "00000000-0000-0000-0000-000000000002",
    "leadName": "Jane Doe",
    "leadImageUrl": null,
    "campaignId": "00000000-0000-0000-0000-000000000003",
    "campaignName": "Example campaign",
    "enrollmentId": "00000000-0000-0000-0000-000000000004",
    "connectedAccountId": null,
    "accountName": null,
    "actorUserId": null,
    "actorName": null,
    "data": {
      "exitReason": "finished"
    }
  }
}

enrollment_stopped

The sequence stopped early; data.exitReason says why.

Set: leadId, campaignId, enrollmentId.

data: exitReason, suppressionReason?

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "enrollment_stopped",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "enrollment_stopped",
    "label": "Sequence stopped",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": null,
    "nodeId": null,
    "leadId": "00000000-0000-0000-0000-000000000002",
    "leadName": "Jane Doe",
    "leadImageUrl": null,
    "campaignId": "00000000-0000-0000-0000-000000000003",
    "campaignName": "Example campaign",
    "enrollmentId": "00000000-0000-0000-0000-000000000004",
    "connectedAccountId": null,
    "accountName": null,
    "actorUserId": null,
    "actorName": null,
    "data": {
      "exitReason": "replied"
    }
  }
}

lead_suppressed

A lead matched a suppression.

Set: leadId, campaignId, enrollmentId, channel.

data: suppressionReason, keyword

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "lead_suppressed",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "lead_suppressed",
    "label": "Lead suppressed",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": "linkedin",
    "nodeId": null,
    "leadId": "00000000-0000-0000-0000-000000000002",
    "leadName": "Jane Doe",
    "leadImageUrl": null,
    "campaignId": "00000000-0000-0000-0000-000000000003",
    "campaignName": "Example campaign",
    "enrollmentId": "00000000-0000-0000-0000-000000000004",
    "connectedAccountId": null,
    "accountName": null,
    "actorUserId": null,
    "actorName": null,
    "data": {
      "suppressionReason": "not_interested",
      "keyword": "not interested"
    }
  }
}

campaign_status_changed

A campaign's status changed, for example it was started or paused.

Set: campaignId.

data: message

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "campaign_status_changed",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "campaign_status_changed",
    "label": "Campaign status changed",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": null,
    "nodeId": null,
    "leadId": null,
    "leadName": null,
    "leadImageUrl": null,
    "campaignId": "00000000-0000-0000-0000-000000000003",
    "campaignName": "Example campaign",
    "enrollmentId": null,
    "connectedAccountId": null,
    "accountName": null,
    "actorUserId": null,
    "actorName": null,
    "data": {
      "message": "draft -> active"
    }
  }
}

campaign_updated

A campaign's name, sequence, schedule, limits or suppression policy was edited; data.changedFields lists which.

Set: campaignId.

data: changedFields

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "campaign_updated",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "campaign_updated",
    "label": "Campaign edited",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": null,
    "nodeId": null,
    "leadId": null,
    "leadName": null,
    "leadImageUrl": null,
    "campaignId": "00000000-0000-0000-0000-000000000003",
    "campaignName": "Example campaign",
    "enrollmentId": null,
    "connectedAccountId": null,
    "accountName": null,
    "actorUserId": null,
    "actorName": null,
    "data": {
      "changedFields": [
        "graph",
        "schedule"
      ]
    }
  }
}

account_connected

A LinkedIn or Instagram account was connected to the workspace for the first time, or again after it was deleted.

Set: connectedAccountId, channel.

data: null

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "account_connected",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "account_connected",
    "label": "Account connected",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": "linkedin",
    "nodeId": null,
    "leadId": null,
    "leadName": null,
    "leadImageUrl": null,
    "campaignId": null,
    "campaignName": null,
    "enrollmentId": null,
    "connectedAccountId": "00000000-0000-0000-0000-000000000005",
    "accountName": "John Doe",
    "actorUserId": null,
    "actorName": null,
    "data": null
  }
}

account_reconnected

A disconnected account works again, because a member signed in to it again or LinkedIn or Instagram reports it healthy.

Set: connectedAccountId, channel.

data: null

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "account_reconnected",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "account_reconnected",
    "label": "Account reconnected",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": "linkedin",
    "nodeId": null,
    "leadId": null,
    "leadName": null,
    "leadImageUrl": null,
    "campaignId": null,
    "campaignName": null,
    "enrollmentId": null,
    "connectedAccountId": "00000000-0000-0000-0000-000000000005",
    "accountName": "John Doe",
    "actorUserId": null,
    "actorName": null,
    "data": null
  }
}

account_deleted

A connected account was deleted.

Set: connectedAccountId, channel.

data: null

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "account_deleted",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "account_deleted",
    "label": "Account deleted",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": "linkedin",
    "nodeId": null,
    "leadId": null,
    "leadName": null,
    "leadImageUrl": null,
    "campaignId": null,
    "campaignName": null,
    "enrollmentId": null,
    "connectedAccountId": "00000000-0000-0000-0000-000000000005",
    "accountName": "John Doe",
    "actorUserId": null,
    "actorName": null,
    "data": null
  }
}

account_paused

A connected account was paused, by its owner or after hitting a limit (data.errorKind).

Set: connectedAccountId, channel.

data: errorKind?, message, properties.pausedUntil?

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "account_paused",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "account_paused",
    "label": "Account paused",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": "linkedin",
    "nodeId": null,
    "leadId": null,
    "leadName": null,
    "leadImageUrl": null,
    "campaignId": null,
    "campaignName": null,
    "enrollmentId": null,
    "connectedAccountId": "00000000-0000-0000-0000-000000000005",
    "accountName": "John Doe",
    "actorUserId": null,
    "actorName": null,
    "data": {
      "errorKind": "rate_limited",
      "message": "Rate limited by the provider",
      "properties": {
        "pausedUntil": "2026-01-01T12:15:00.000Z"
      }
    }
  }
}

account_resumed

A paused connected account was resumed, by its owner or when billing was restored.

Set: connectedAccountId, channel.

data: message

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "account_resumed",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "account_resumed",
    "label": "Account resumed",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": "linkedin",
    "nodeId": null,
    "leadId": null,
    "leadName": null,
    "leadImageUrl": null,
    "campaignId": null,
    "campaignName": null,
    "enrollmentId": null,
    "connectedAccountId": "00000000-0000-0000-0000-000000000005",
    "accountName": "John Doe",
    "actorUserId": null,
    "actorName": null,
    "data": {
      "message": "Resumed by hand"
    }
  }
}

account_disconnected

A connected account stopped working: it needs signing in again (data.errorKind is auth_required) or LinkedIn or Instagram disconnected it (disconnected). Its campaigns wait until it is reconnected.

Set: connectedAccountId, channel.

data: errorKind

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "account_disconnected",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "account_disconnected",
    "label": "Account disconnected",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": "linkedin",
    "nodeId": null,
    "leadId": null,
    "leadName": null,
    "leadImageUrl": null,
    "campaignId": null,
    "campaignName": null,
    "enrollmentId": null,
    "connectedAccountId": "00000000-0000-0000-0000-000000000005",
    "accountName": "John Doe",
    "actorUserId": null,
    "actorName": null,
    "data": {
      "errorKind": "auth_required"
    }
  }
}

account_suspended

A connected account was signed out and stopped, because the workspace's billing lapsed or its owner was removed from the workspace (data.message). It has to be connected again to be used.

Set: connectedAccountId, channel.

data: message

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "account_suspended",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "account_suspended",
    "label": "Account suspended",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": "linkedin",
    "nodeId": null,
    "leadId": null,
    "leadName": null,
    "leadImageUrl": null,
    "campaignId": null,
    "campaignName": null,
    "enrollmentId": null,
    "connectedAccountId": "00000000-0000-0000-0000-000000000005",
    "accountName": "John Doe",
    "actorUserId": null,
    "actorName": null,
    "data": {
      "message": "billing"
    }
  }
}

account_limits_updated

A connected account's usage limits were changed; data.changes lists each limit.

Set: connectedAccountId, channel.

data: changes

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "account_limits_updated",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "account_limits_updated",
    "label": "Account limits changed",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": "linkedin",
    "nodeId": null,
    "leadId": null,
    "leadName": null,
    "leadImageUrl": null,
    "campaignId": null,
    "campaignName": null,
    "enrollmentId": null,
    "connectedAccountId": "00000000-0000-0000-0000-000000000005",
    "accountName": "John Doe",
    "actorUserId": null,
    "actorName": null,
    "data": {
      "changes": {
        "linkedin_invitation.day": {
          "from": "20",
          "to": "25"
        },
        "linkedin_invitation.week": {
          "from": "100",
          "to": "120"
        }
      }
    }
  }
}

account_access_granted

A member (data.member) was allowed to use a connected account.

Set: connectedAccountId, channel.

data: member

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "account_access_granted",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "account_access_granted",
    "label": "Account access granted",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": "linkedin",
    "nodeId": null,
    "leadId": null,
    "leadName": null,
    "leadImageUrl": null,
    "campaignId": null,
    "campaignName": null,
    "enrollmentId": null,
    "connectedAccountId": "00000000-0000-0000-0000-000000000005",
    "accountName": "John Doe",
    "actorUserId": null,
    "actorName": null,
    "data": {
      "member": {
        "userId": "00000000-0000-0000-0000-000000000006",
        "name": "Ada Lovelace"
      }
    }
  }
}

account_access_revoked

A member (data.member) can no longer use a connected account. Campaigns they started with it pause.

Set: connectedAccountId, channel.

data: member

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "account_access_revoked",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "account_access_revoked",
    "label": "Account access removed",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": "linkedin",
    "nodeId": null,
    "leadId": null,
    "leadName": null,
    "leadImageUrl": null,
    "campaignId": null,
    "campaignName": null,
    "enrollmentId": null,
    "connectedAccountId": "00000000-0000-0000-0000-000000000005",
    "accountName": "John Doe",
    "actorUserId": null,
    "actorName": null,
    "data": {
      "member": {
        "userId": "00000000-0000-0000-0000-000000000006",
        "name": "Ada Lovelace"
      }
    }
  }
}

account_sharing_changed

A connected account was shared with the whole workspace, or stopped being shared.

Set: connectedAccountId, channel.

data: changes

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "account_sharing_changed",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "account_sharing_changed",
    "label": "Account sharing changed",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": "linkedin",
    "nodeId": null,
    "leadId": null,
    "leadName": null,
    "leadImageUrl": null,
    "campaignId": null,
    "campaignName": null,
    "enrollmentId": null,
    "connectedAccountId": "00000000-0000-0000-0000-000000000005",
    "accountName": "John Doe",
    "actorUserId": null,
    "actorName": null,
    "data": {
      "changes": {
        "sharedWithWorkspace": {
          "from": "false",
          "to": "true"
        }
      }
    }
  }
}

member_invited

Someone was invited to the workspace.

Set: .

data: email, role

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "member_invited",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "member_invited",
    "label": "Member invited",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": null,
    "nodeId": null,
    "leadId": null,
    "leadName": null,
    "leadImageUrl": null,
    "campaignId": null,
    "campaignName": null,
    "enrollmentId": null,
    "connectedAccountId": null,
    "accountName": null,
    "actorUserId": null,
    "actorName": null,
    "data": {
      "email": "ada@example.com",
      "role": "member"
    }
  }
}

member_invitation_revoked

An invitation to the workspace was withdrawn.

Set: .

data: email, role

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "member_invitation_revoked",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "member_invitation_revoked",
    "label": "Invitation revoked",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": null,
    "nodeId": null,
    "leadId": null,
    "leadName": null,
    "leadImageUrl": null,
    "campaignId": null,
    "campaignName": null,
    "enrollmentId": null,
    "connectedAccountId": null,
    "accountName": null,
    "actorUserId": null,
    "actorName": null,
    "data": {
      "email": "ada@example.com",
      "role": "member"
    }
  }
}

member_joined

Someone accepted an invitation and joined.

Set: .

data: member, role

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "member_joined",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "member_joined",
    "label": "Member joined",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": null,
    "nodeId": null,
    "leadId": null,
    "leadName": null,
    "leadImageUrl": null,
    "campaignId": null,
    "campaignName": null,
    "enrollmentId": null,
    "connectedAccountId": null,
    "accountName": null,
    "actorUserId": null,
    "actorName": null,
    "data": {
      "member": {
        "userId": "00000000-0000-0000-0000-000000000006",
        "name": "Ada Lovelace"
      },
      "role": "member"
    }
  }
}

member_role_changed

A member's role changed.

Set: .

data: member, changes

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "member_role_changed",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "member_role_changed",
    "label": "Member role changed",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": null,
    "nodeId": null,
    "leadId": null,
    "leadName": null,
    "leadImageUrl": null,
    "campaignId": null,
    "campaignName": null,
    "enrollmentId": null,
    "connectedAccountId": null,
    "accountName": null,
    "actorUserId": null,
    "actorName": null,
    "data": {
      "member": {
        "userId": "00000000-0000-0000-0000-000000000006",
        "name": "Ada Lovelace"
      },
      "changes": {
        "role": {
          "from": "member",
          "to": "admin"
        }
      }
    }
  }
}

member_removed

An admin removed a member. Their accounts are suspended and their campaigns pause.

Set: .

data: member, role

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "member_removed",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "member_removed",
    "label": "Member removed",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": null,
    "nodeId": null,
    "leadId": null,
    "leadName": null,
    "leadImageUrl": null,
    "campaignId": null,
    "campaignName": null,
    "enrollmentId": null,
    "connectedAccountId": null,
    "accountName": null,
    "actorUserId": null,
    "actorName": null,
    "data": {
      "member": {
        "userId": "00000000-0000-0000-0000-000000000006",
        "name": "Ada Lovelace"
      },
      "role": "member"
    }
  }
}

member_left

A member deleted their Needle account.

Set: .

data: member, role

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "member_left",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "member_left",
    "label": "Member left",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": null,
    "nodeId": null,
    "leadId": null,
    "leadName": null,
    "leadImageUrl": null,
    "campaignId": null,
    "campaignName": null,
    "enrollmentId": null,
    "connectedAccountId": null,
    "accountName": null,
    "actorUserId": null,
    "actorName": null,
    "data": {
      "member": {
        "userId": "00000000-0000-0000-0000-000000000006",
        "name": "Ada Lovelace"
      },
      "role": "member"
    }
  }
}

api_key_created

An API key was created.

Set: .

data: apiKey

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "api_key_created",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "api_key_created",
    "label": "API key created",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": null,
    "nodeId": null,
    "leadId": null,
    "leadName": null,
    "leadImageUrl": null,
    "campaignId": null,
    "campaignName": null,
    "enrollmentId": null,
    "connectedAccountId": null,
    "accountName": null,
    "actorUserId": null,
    "actorName": null,
    "data": {
      "apiKey": {
        "id": "00000000-0000-0000-0000-000000000007",
        "name": "CRM sync"
      }
    }
  }
}

api_key_revoked

An API key was disabled.

Set: .

data: apiKey

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "api_key_revoked",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "api_key_revoked",
    "label": "API key disabled",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": null,
    "nodeId": null,
    "leadId": null,
    "leadName": null,
    "leadImageUrl": null,
    "campaignId": null,
    "campaignName": null,
    "enrollmentId": null,
    "connectedAccountId": null,
    "accountName": null,
    "actorUserId": null,
    "actorName": null,
    "data": {
      "apiKey": {
        "id": "00000000-0000-0000-0000-000000000007",
        "name": "CRM sync"
      }
    }
  }
}

api_key_enabled

A disabled API key was enabled again.

Set: .

data: apiKey

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "api_key_enabled",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "api_key_enabled",
    "label": "API key enabled",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": null,
    "nodeId": null,
    "leadId": null,
    "leadName": null,
    "leadImageUrl": null,
    "campaignId": null,
    "campaignName": null,
    "enrollmentId": null,
    "connectedAccountId": null,
    "accountName": null,
    "actorUserId": null,
    "actorName": null,
    "data": {
      "apiKey": {
        "id": "00000000-0000-0000-0000-000000000007",
        "name": "CRM sync"
      }
    }
  }
}

api_key_deleted

An API key was deleted.

Set: .

data: apiKey

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "api_key_deleted",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "api_key_deleted",
    "label": "API key deleted",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": null,
    "nodeId": null,
    "leadId": null,
    "leadName": null,
    "leadImageUrl": null,
    "campaignId": null,
    "campaignName": null,
    "enrollmentId": null,
    "connectedAccountId": null,
    "accountName": null,
    "actorUserId": null,
    "actorName": null,
    "data": {
      "apiKey": {
        "id": "00000000-0000-0000-0000-000000000007",
        "name": "CRM sync"
      }
    }
  }
}

webhook_created

A webhook was added.

Set: .

data: webhook

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "webhook_created",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "webhook_created",
    "label": "Webhook added",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": null,
    "nodeId": null,
    "leadId": null,
    "leadName": null,
    "leadImageUrl": null,
    "campaignId": null,
    "campaignName": null,
    "enrollmentId": null,
    "connectedAccountId": null,
    "accountName": null,
    "actorUserId": null,
    "actorName": null,
    "data": {
      "webhook": {
        "id": "00000000-0000-0000-0000-000000000008",
        "host": "hooks.example.com"
      }
    }
  }
}

webhook_updated

A webhook's URL or headers changed; data.changedFields lists which.

Set: .

data: webhook, changedFields

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "webhook_updated",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "webhook_updated",
    "label": "Webhook changed",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": null,
    "nodeId": null,
    "leadId": null,
    "leadName": null,
    "leadImageUrl": null,
    "campaignId": null,
    "campaignName": null,
    "enrollmentId": null,
    "connectedAccountId": null,
    "accountName": null,
    "actorUserId": null,
    "actorName": null,
    "data": {
      "webhook": {
        "id": "00000000-0000-0000-0000-000000000008",
        "host": "hooks.example.com"
      },
      "changedFields": [
        "url",
        "headers"
      ]
    }
  }
}

webhook_deleted

A webhook was removed.

Set: .

data: webhook

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "webhook_deleted",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "webhook_deleted",
    "label": "Webhook removed",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": null,
    "nodeId": null,
    "leadId": null,
    "leadName": null,
    "leadImageUrl": null,
    "campaignId": null,
    "campaignName": null,
    "enrollmentId": null,
    "connectedAccountId": null,
    "accountName": null,
    "actorUserId": null,
    "actorName": null,
    "data": {
      "webhook": {
        "id": "00000000-0000-0000-0000-000000000008",
        "host": "hooks.example.com"
      }
    }
  }
}

suppression_added

A lead or company was added to the do-not-contact list by a member or through the API.

Set: leadId. leadId is null for a company-wide entry, which sets data.companyDomain instead.

data: suppressionId, suppressionReason, companyDomain?

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "suppression_added",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "suppression_added",
    "label": "Added to do-not-contact list",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": null,
    "nodeId": null,
    "leadId": "00000000-0000-0000-0000-000000000002",
    "leadName": "Jane Doe",
    "leadImageUrl": null,
    "campaignId": null,
    "campaignName": null,
    "enrollmentId": null,
    "connectedAccountId": null,
    "accountName": null,
    "actorUserId": null,
    "actorName": null,
    "data": {
      "suppressionId": "00000000-0000-0000-0000-000000000009",
      "suppressionReason": "existing_customer"
    }
  }
}

suppression_removed

An entry was removed from the do-not-contact list.

Set: leadId. leadId is null for a company-wide entry, which sets data.companyDomain instead.

data: suppressionId, suppressionReason, companyDomain?

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "suppression_removed",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "suppression_removed",
    "label": "Removed from do-not-contact list",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": null,
    "nodeId": null,
    "leadId": "00000000-0000-0000-0000-000000000002",
    "leadName": "Jane Doe",
    "leadImageUrl": null,
    "campaignId": null,
    "campaignName": null,
    "enrollmentId": null,
    "connectedAccountId": null,
    "accountName": null,
    "actorUserId": null,
    "actorName": null,
    "data": {
      "suppressionId": "00000000-0000-0000-0000-000000000009",
      "suppressionReason": "existing_customer"
    }
  }
}

linkedin_profile_visited

A LinkedIn profile was visited.

Account-sensitive. See Who sees an event.

Set: leadId, campaignId, enrollmentId, connectedAccountId, channel, nodeId. From the API or MCP, campaignId, enrollmentId, and nodeId are null, and leadId is set only when the action was aimed at a lead.

data: action, profile?, message?

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "linkedin_profile_visited",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "linkedin_profile_visited",
    "label": "Profile visited",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": "linkedin",
    "nodeId": "step_1",
    "leadId": "00000000-0000-0000-0000-000000000002",
    "leadName": "Jane Doe",
    "leadImageUrl": null,
    "campaignId": "00000000-0000-0000-0000-000000000003",
    "campaignName": "Example campaign",
    "enrollmentId": "00000000-0000-0000-0000-000000000004",
    "connectedAccountId": "00000000-0000-0000-0000-000000000005",
    "accountName": "John Doe",
    "actorUserId": null,
    "actorName": null,
    "data": {
      "action": "linkedin_profile_view",
      "text": null,
      "profile": {
        "name": "Jane Doe",
        "identity": "jane-doe",
        "url": null,
        "imageUrl": null
      }
    }
  }
}

linkedin_invite_sent

A LinkedIn connection request was sent.

Account-sensitive. See Who sees an event.

Set: leadId, campaignId, enrollmentId, connectedAccountId, channel, nodeId. From the API or MCP, campaignId, enrollmentId, and nodeId are null, and leadId is set only when the action was aimed at a lead.

data: action, text?, message?

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "linkedin_invite_sent",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "linkedin_invite_sent",
    "label": "Connection request sent",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": "linkedin",
    "nodeId": "step_1",
    "leadId": "00000000-0000-0000-0000-000000000002",
    "leadName": "Jane Doe",
    "leadImageUrl": null,
    "campaignId": "00000000-0000-0000-0000-000000000003",
    "campaignName": "Example campaign",
    "enrollmentId": "00000000-0000-0000-0000-000000000004",
    "connectedAccountId": "00000000-0000-0000-0000-000000000005",
    "accountName": "John Doe",
    "actorUserId": null,
    "actorName": null,
    "data": {
      "action": "linkedin_invitation",
      "text": "Hi Jane, would love to connect."
    }
  }
}

linkedin_invite_withdrawn

A LinkedIn connection request was withdrawn.

Account-sensitive. See Who sees an event.

Set: leadId, campaignId, enrollmentId, connectedAccountId, channel, nodeId. From the API or MCP, campaignId, enrollmentId, and nodeId are null, and leadId is set only when the action was aimed at a lead.

data: action, message?

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "linkedin_invite_withdrawn",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "linkedin_invite_withdrawn",
    "label": "Connection request withdrawn",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": "linkedin",
    "nodeId": "step_1",
    "leadId": "00000000-0000-0000-0000-000000000002",
    "leadName": "Jane Doe",
    "leadImageUrl": null,
    "campaignId": "00000000-0000-0000-0000-000000000003",
    "campaignName": "Example campaign",
    "enrollmentId": "00000000-0000-0000-0000-000000000004",
    "connectedAccountId": "00000000-0000-0000-0000-000000000005",
    "accountName": "John Doe",
    "actorUserId": null,
    "actorName": null,
    "data": {
      "action": "linkedin_cancel_invitation",
      "text": null
    }
  }
}

linkedin_message_sent

A LinkedIn message was sent, through Needle or by the account owner in LinkedIn (data.sentOutsideNeedle).

Account-sensitive. See Who sees an event.

Set: leadId, campaignId, enrollmentId, connectedAccountId, channel, nodeId. From the API or MCP, campaignId, enrollmentId, and nodeId are null, and leadId is set only when the action was aimed at a lead.

data: action, text, subject?, message?

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "linkedin_message_sent",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "linkedin_message_sent",
    "label": "Message sent",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": "linkedin",
    "nodeId": "step_1",
    "leadId": "00000000-0000-0000-0000-000000000002",
    "leadName": "Jane Doe",
    "leadImageUrl": null,
    "campaignId": "00000000-0000-0000-0000-000000000003",
    "campaignName": "Example campaign",
    "enrollmentId": "00000000-0000-0000-0000-000000000004",
    "connectedAccountId": "00000000-0000-0000-0000-000000000005",
    "accountName": "John Doe",
    "actorUserId": null,
    "actorName": null,
    "data": {
      "action": "linkedin_message",
      "text": "Hi Jane, open to a quick chat?",
      "subject": null
    }
  }
}

linkedin_follow_sent

A LinkedIn profile was followed.

Not sent yet.

linkedin_unfollowed

A LinkedIn profile was unfollowed.

Not sent yet.

linkedin_invite_accepted

A LinkedIn connection request was accepted.

Account-sensitive. See Who sees an event.

Set: connectedAccountId, channel. leadId is set too when the person is one of your leads, and campaignId, enrollmentId, and nodeId when they are still in one of your campaigns.

data: profile?

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "linkedin_invite_accepted",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "linkedin_invite_accepted",
    "label": "Connection request accepted",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": "linkedin",
    "nodeId": null,
    "leadId": null,
    "leadName": null,
    "leadImageUrl": null,
    "campaignId": null,
    "campaignName": null,
    "enrollmentId": null,
    "connectedAccountId": "00000000-0000-0000-0000-000000000005",
    "accountName": "John Doe",
    "actorUserId": null,
    "actorName": null,
    "data": {
      "profile": {
        "identity": "jane-doe",
        "url": "https://www.linkedin.com/in/jane-doe"
      }
    }
  }
}

linkedin_message_received

A LinkedIn reply was received.

Account-sensitive. See Who sees an event.

Set: connectedAccountId, channel. leadId is set too when the person is one of your leads, and campaignId, enrollmentId, and nodeId when they are still in one of your campaigns.

data: text, profile?

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "linkedin_message_received",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "linkedin_message_received",
    "label": "Reply received",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": "linkedin",
    "nodeId": null,
    "leadId": null,
    "leadName": null,
    "leadImageUrl": null,
    "campaignId": null,
    "campaignName": null,
    "enrollmentId": null,
    "connectedAccountId": "00000000-0000-0000-0000-000000000005",
    "accountName": "John Doe",
    "actorUserId": null,
    "actorName": null,
    "data": {
      "text": "Thanks, happy to chat next week.",
      "profile": {
        "name": "Jane Doe",
        "identity": "jane-doe",
        "url": "https://www.linkedin.com/in/jane-doe"
      }
    }
  }
}

linkedin_post_commented

A comment was posted on LinkedIn.

Account-sensitive. See Who sees an event.

Set: connectedAccountId, channel.

data: action, text

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "linkedin_post_commented",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "linkedin_post_commented",
    "label": "Comment posted",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": "linkedin",
    "nodeId": null,
    "leadId": null,
    "leadName": null,
    "leadImageUrl": null,
    "campaignId": null,
    "campaignName": null,
    "enrollmentId": null,
    "connectedAccountId": "00000000-0000-0000-0000-000000000005",
    "accountName": "John Doe",
    "actorUserId": null,
    "actorName": null,
    "data": {
      "action": "linkedin_comment",
      "text": "Great point on pricing."
    }
  }
}

linkedin_post_reacted

A reaction was added to a LinkedIn post.

Account-sensitive. See Who sees an event.

Set: connectedAccountId, channel.

data: action

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "linkedin_post_reacted",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "linkedin_post_reacted",
    "label": "Post reaction added",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": "linkedin",
    "nodeId": null,
    "leadId": null,
    "leadName": null,
    "leadImageUrl": null,
    "campaignId": null,
    "campaignName": null,
    "enrollmentId": null,
    "connectedAccountId": "00000000-0000-0000-0000-000000000005",
    "accountName": "John Doe",
    "actorUserId": null,
    "actorName": null,
    "data": {
      "action": "linkedin_reaction"
    }
  }
}

instagram_message_sent

An Instagram message was sent, through Needle or by the account owner in Instagram (data.sentOutsideNeedle).

Account-sensitive. See Who sees an event.

Set: leadId, campaignId, enrollmentId, connectedAccountId, channel, nodeId. From the API or MCP, campaignId, enrollmentId, and nodeId are null, and leadId is set only when the action was aimed at a lead.

data: action, text, message?

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "instagram_message_sent",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "instagram_message_sent",
    "label": "Message sent",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": "instagram",
    "nodeId": "step_1",
    "leadId": "00000000-0000-0000-0000-000000000002",
    "leadName": "Jane Doe",
    "leadImageUrl": null,
    "campaignId": "00000000-0000-0000-0000-000000000003",
    "campaignName": "Example campaign",
    "enrollmentId": "00000000-0000-0000-0000-000000000004",
    "connectedAccountId": "00000000-0000-0000-0000-000000000005",
    "accountName": "John Doe",
    "actorUserId": null,
    "actorName": null,
    "data": {
      "action": "instagram_message",
      "text": "Hi Jane, love your shop!"
    }
  }
}

instagram_profile_visited

An Instagram profile was visited.

Account-sensitive. See Who sees an event.

Set: leadId, campaignId, enrollmentId, connectedAccountId, channel, nodeId. From the API or MCP, campaignId, enrollmentId, and nodeId are null, and leadId is set only when the action was aimed at a lead.

data: action, profile?, message?

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "instagram_profile_visited",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "instagram_profile_visited",
    "label": "Profile visited",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": "instagram",
    "nodeId": "step_1",
    "leadId": "00000000-0000-0000-0000-000000000002",
    "leadName": "Jane Doe",
    "leadImageUrl": null,
    "campaignId": "00000000-0000-0000-0000-000000000003",
    "campaignName": "Example campaign",
    "enrollmentId": "00000000-0000-0000-0000-000000000004",
    "connectedAccountId": "00000000-0000-0000-0000-000000000005",
    "accountName": "John Doe",
    "actorUserId": null,
    "actorName": null,
    "data": {
      "action": "instagram_profile_view",
      "text": null,
      "profile": {
        "name": "Jane Doe",
        "identity": "janedoe",
        "url": "https://www.instagram.com/janedoe/",
        "imageUrl": null
      }
    }
  }
}

instagram_follow_sent

An Instagram profile was followed.

Account-sensitive. See Who sees an event.

Set: leadId, campaignId, enrollmentId, connectedAccountId, channel, nodeId. From the API or MCP, campaignId, enrollmentId, and nodeId are null, and leadId is set only when the action was aimed at a lead.

data: action, message?

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "instagram_follow_sent",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "instagram_follow_sent",
    "label": "Followed",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": "instagram",
    "nodeId": "step_1",
    "leadId": "00000000-0000-0000-0000-000000000002",
    "leadName": "Jane Doe",
    "leadImageUrl": null,
    "campaignId": "00000000-0000-0000-0000-000000000003",
    "campaignName": "Example campaign",
    "enrollmentId": "00000000-0000-0000-0000-000000000004",
    "connectedAccountId": "00000000-0000-0000-0000-000000000005",
    "accountName": "John Doe",
    "actorUserId": null,
    "actorName": null,
    "data": {
      "action": "instagram_follow",
      "text": null
    }
  }
}

instagram_unfollowed

An Instagram profile was unfollowed.

Account-sensitive. See Who sees an event.

Set: leadId, campaignId, enrollmentId, connectedAccountId, channel, nodeId. From the API or MCP, campaignId, enrollmentId, and nodeId are null, and leadId is set only when the action was aimed at a lead.

data: action, message?

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "instagram_unfollowed",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "instagram_unfollowed",
    "label": "Unfollowed",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": "instagram",
    "nodeId": "step_1",
    "leadId": "00000000-0000-0000-0000-000000000002",
    "leadName": "Jane Doe",
    "leadImageUrl": null,
    "campaignId": "00000000-0000-0000-0000-000000000003",
    "campaignName": "Example campaign",
    "enrollmentId": "00000000-0000-0000-0000-000000000004",
    "connectedAccountId": "00000000-0000-0000-0000-000000000005",
    "accountName": "John Doe",
    "actorUserId": null,
    "actorName": null,
    "data": {
      "action": "instagram_unfollow",
      "text": null
    }
  }
}

instagram_message_received

An Instagram reply was received.

Account-sensitive. See Who sees an event.

Set: connectedAccountId, channel. leadId is set too when the person is one of your leads, and campaignId, enrollmentId, and nodeId when they are still in one of your campaigns.

data: text, profile?

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "instagram_message_received",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "instagram_message_received",
    "label": "Reply received",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": "instagram",
    "nodeId": null,
    "leadId": null,
    "leadName": null,
    "leadImageUrl": null,
    "campaignId": null,
    "campaignName": null,
    "enrollmentId": null,
    "connectedAccountId": "00000000-0000-0000-0000-000000000005",
    "accountName": "John Doe",
    "actorUserId": null,
    "actorName": null,
    "data": {
      "text": "Sounds good!",
      "profile": {
        "name": "Jane Doe",
        "identity": "janedoe",
        "url": "https://www.instagram.com/janedoe"
      }
    }
  }
}

instagram_post_commented

A comment was posted on Instagram.

Account-sensitive. See Who sees an event.

Set: connectedAccountId, channel.

data: action, text

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "instagram_post_commented",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "instagram_post_commented",
    "label": "Commented on a post",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": "instagram",
    "nodeId": null,
    "leadId": null,
    "leadName": null,
    "leadImageUrl": null,
    "campaignId": null,
    "campaignName": null,
    "enrollmentId": null,
    "connectedAccountId": "00000000-0000-0000-0000-000000000005",
    "accountName": "John Doe",
    "actorUserId": null,
    "actorName": null,
    "data": {
      "action": "instagram_comment",
      "text": "Love this."
    }
  }
}

instagram_post_reacted

An Instagram post was liked.

Account-sensitive. See Who sees an event.

Set: connectedAccountId, channel.

data: action

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "instagram_post_reacted",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "instagram_post_reacted",
    "label": "Liked a post",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": "instagram",
    "nodeId": null,
    "leadId": null,
    "leadName": null,
    "leadImageUrl": null,
    "campaignId": null,
    "campaignName": null,
    "enrollmentId": null,
    "connectedAccountId": "00000000-0000-0000-0000-000000000005",
    "accountName": "John Doe",
    "actorUserId": null,
    "actorName": null,
    "data": {
      "action": "instagram_reaction"
    }
  }
}

instagram_message_reacted

A reaction was added to an Instagram message.

Account-sensitive. See Who sees an event.

Set: connectedAccountId, channel.

data: action

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "instagram_message_reacted",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "instagram_message_reacted",
    "label": "Reacted to a message",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": "instagram",
    "nodeId": null,
    "leadId": null,
    "leadName": null,
    "leadImageUrl": null,
    "campaignId": null,
    "campaignName": null,
    "enrollmentId": null,
    "connectedAccountId": "00000000-0000-0000-0000-000000000005",
    "accountName": "John Doe",
    "actorUserId": null,
    "actorName": null,
    "data": {
      "action": "instagram_reaction"
    }
  }
}

instagram_post_created

An Instagram post was published.

Account-sensitive. See Who sees an event.

Set: connectedAccountId, channel.

data: action, text

{
  "version": "v1",
  "id": "00000000-0000-0000-0000-000000000001",
  "type": "instagram_post_created",
  "timestamp": "2026-01-01T12:00:00.000Z",
  "data": {
    "id": "00000000-0000-0000-0000-000000000001",
    "type": "instagram_post_created",
    "label": "Post published",
    "occurredAt": "2026-01-01T12:00:00.000Z",
    "channel": "instagram",
    "nodeId": null,
    "leadId": null,
    "leadName": null,
    "leadImageUrl": null,
    "campaignId": null,
    "campaignName": null,
    "enrollmentId": null,
    "connectedAccountId": "00000000-0000-0000-0000-000000000005",
    "accountName": "John Doe",
    "actorUserId": null,
    "actorName": null,
    "data": {
      "action": "instagram_post",
      "text": "New office, same team."
    }
  }
}

Versioning

Every body has "version": "v1". Within v1, new event types and new fields can be added, but fields are not removed or renamed. Ignore types and fields you do not know.

Search docs

Search documentation, API reference, and MCP tools

We use cookies to enhance your experience on Needle and keep your data secure. Privacy Policy