Event catalogue
One entry per event that GET /v1/webhooks/events lists, at a stable anchor: /reference/webhooks/catalogue#<event>. Each entry says when the event fires, its source, whether a new webhook gets it by default, how late it can arrive, how to subscribe (CLI first) and a full example delivery with every key the event can carry.
A webhook has one source. Omit account_ids (REST) to cover every account you can operate, now and later; omit events for the source's default set. Every webhook also takes motion_ids to receive only the events of those Motions.
The examples show a Motion-linked delivery where one exists: outside a Motion, motion_id, enrollment_id, motion_name and contact are null on message.* and connection.accepted.
Messaging events
message.received
An inbound message arrived in any chat (classic / InMail).
- Source:
messaging - Subscription: default: subscribed when you omit
events - Latency: Real time: seconds after LinkedIn reports it.
Subscribe with the CLI:
curviate webhook create --source messaging --events message.received --request-url https://hooks.example.com/curviateOr with the REST API:
curl -X POST https://api.curviate.com/v1/webhooks \
-H "Authorization: Bearer cvt_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"source": "messaging",
"request_url": "https://hooks.example.com/curviate",
"events": [
"message.received"
]
}'Example delivery:
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "message.received",
"data": {
"account_id": "acc_YOUR_ACCOUNT_ID",
"event": "message.received",
"chat_id": "chat_YOUR_CHAT_ID",
"message_id": "msg_YOUR_MESSAGE_ID",
"text": "Hello, I saw your profile and wanted to connect.",
"sender": {
"name": "Alex Jordan",
"profile_url": "https://www.linkedin.com/in/alexjordan",
"provider_id": "urn:li:member:123456789"
},
"attachments": [],
"motion_id": "mot_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"enrollment_id": "enr_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"motion_name": "Q4 founders outreach",
"contact": {
"id": "con_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"linkedin_url": "https://www.linkedin.com/in/alexjordan",
"full_name": "Alex Jordan",
"first_name": "Alex",
"last_name": "Jordan",
"headline": "Head of Operations at Northwind",
"job_title": "Head of Operations",
"company": "Northwind",
"email": "alex@northwind.example",
"location": "Berlin, Germany",
"about": "Operations leader in logistics.",
"extra": {
"crm_id": "0035e00000AbCdE"
},
"tags": [
"in-conversation"
]
},
"occurred_at": "2026-05-28T14:22:05.000Z"
},
"delivered_at": "2026-05-28T14:22:06.789Z"
}message.read
A message in a chat was read by the recipient.
- Source:
messaging - Subscription: opt-in: name it in
events - Latency: Real time: seconds after LinkedIn reports it.
Subscribe with the CLI:
curviate webhook create --source messaging --events message.read --request-url https://hooks.example.com/curviateOr with the REST API:
curl -X POST https://api.curviate.com/v1/webhooks \
-H "Authorization: Bearer cvt_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"source": "messaging",
"request_url": "https://hooks.example.com/curviate",
"events": [
"message.read"
]
}'Example delivery:
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "message.read",
"data": {
"account_id": "acc_YOUR_ACCOUNT_ID",
"event": "message.read",
"chat_id": "chat_YOUR_CHAT_ID",
"message_id": "msg_YOUR_MESSAGE_ID",
"text": "Hello, I saw your profile and wanted to connect.",
"sender": {
"name": "Alex Jordan",
"profile_url": "https://www.linkedin.com/in/alexjordan",
"provider_id": "urn:li:member:123456789"
},
"read_by": "urn:li:member:987654321",
"attachments": [],
"motion_id": "mot_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"enrollment_id": "enr_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"motion_name": "Q4 founders outreach",
"contact": {
"id": "con_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"linkedin_url": "https://www.linkedin.com/in/alexjordan",
"full_name": "Alex Jordan",
"first_name": "Alex",
"last_name": "Jordan",
"headline": "Head of Operations at Northwind",
"job_title": "Head of Operations",
"company": "Northwind",
"email": "alex@northwind.example",
"location": "Berlin, Germany",
"about": "Operations leader in logistics.",
"extra": {
"crm_id": "0035e00000AbCdE"
},
"tags": [
"in-conversation"
]
},
"occurred_at": "2026-05-28T14:25:00.000Z"
},
"delivered_at": "2026-05-28T14:25:01.012Z"
}message.reaction
A reaction was added to a message.
- Source:
messaging - Subscription: opt-in: name it in
events - Latency: Real time: seconds after LinkedIn reports it.
Subscribe with the CLI:
curviate webhook create --source messaging --events message.reaction --request-url https://hooks.example.com/curviateOr with the REST API:
curl -X POST https://api.curviate.com/v1/webhooks \
-H "Authorization: Bearer cvt_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"source": "messaging",
"request_url": "https://hooks.example.com/curviate",
"events": [
"message.reaction"
]
}'Example delivery:
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "message.reaction",
"data": {
"account_id": "acc_YOUR_ACCOUNT_ID",
"event": "message.reaction",
"chat_id": "chat_YOUR_CHAT_ID",
"message_id": "msg_YOUR_MESSAGE_ID",
"text": "Thanks for reaching out, happy to connect.",
"reaction": "👍",
"sender": {
"name": "Alex Jordan",
"profile_url": "https://www.linkedin.com/in/alexjordan",
"provider_id": "urn:li:member:123456789"
},
"attachments": [],
"motion_id": "mot_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"enrollment_id": "enr_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"motion_name": "Q4 founders outreach",
"contact": {
"id": "con_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"linkedin_url": "https://www.linkedin.com/in/alexjordan",
"full_name": "Alex Jordan",
"first_name": "Alex",
"last_name": "Jordan",
"headline": "Head of Operations at Northwind",
"job_title": "Head of Operations",
"company": "Northwind",
"email": "alex@northwind.example",
"location": "Berlin, Germany",
"about": "Operations leader in logistics.",
"extra": {
"crm_id": "0035e00000AbCdE"
},
"tags": [
"in-conversation"
]
},
"occurred_at": "2026-05-28T14:26:30.000Z"
},
"delivered_at": "2026-05-28T14:26:31.234Z"
}message.edited
A message was edited after send.
- Source:
messaging - Subscription: opt-in: name it in
events - Latency: Real time: seconds after LinkedIn reports it.
Subscribe with the CLI:
curviate webhook create --source messaging --events message.edited --request-url https://hooks.example.com/curviateOr with the REST API:
curl -X POST https://api.curviate.com/v1/webhooks \
-H "Authorization: Bearer cvt_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"source": "messaging",
"request_url": "https://hooks.example.com/curviate",
"events": [
"message.edited"
]
}'Example delivery:
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "message.edited",
"data": {
"account_id": "acc_YOUR_ACCOUNT_ID",
"event": "message.edited",
"chat_id": "chat_YOUR_CHAT_ID",
"message_id": "msg_YOUR_MESSAGE_ID",
"text": "Thanks for reaching out, let's schedule a call.",
"sender": {
"name": "Jordan Lee",
"profile_url": "https://www.linkedin.com/in/jordanlee",
"provider_id": "urn:li:member:987654321"
},
"attachments": [],
"motion_id": "mot_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"enrollment_id": "enr_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"motion_name": "Q4 founders outreach",
"contact": {
"id": "con_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"linkedin_url": "https://www.linkedin.com/in/alexjordan",
"full_name": "Alex Jordan",
"first_name": "Alex",
"last_name": "Jordan",
"headline": "Head of Operations at Northwind",
"job_title": "Head of Operations",
"company": "Northwind",
"email": "alex@northwind.example",
"location": "Berlin, Germany",
"about": "Operations leader in logistics.",
"extra": {
"crm_id": "0035e00000AbCdE"
},
"tags": [
"in-conversation"
]
},
"occurred_at": "2026-05-28T14:27:45.000Z"
},
"delivered_at": "2026-05-28T14:27:46.789Z"
}message.deleted
A message was deleted.
- Source:
messaging - Subscription: opt-in: name it in
events - Latency: Real time: seconds after LinkedIn reports it.
Subscribe with the CLI:
curviate webhook create --source messaging --events message.deleted --request-url https://hooks.example.com/curviateOr with the REST API:
curl -X POST https://api.curviate.com/v1/webhooks \
-H "Authorization: Bearer cvt_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"source": "messaging",
"request_url": "https://hooks.example.com/curviate",
"events": [
"message.deleted"
]
}'Example delivery:
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "message.deleted",
"data": {
"account_id": "acc_YOUR_ACCOUNT_ID",
"event": "message.deleted",
"chat_id": "chat_YOUR_CHAT_ID",
"message_id": "msg_YOUR_MESSAGE_ID",
"sender": {
"name": "Jordan Lee",
"profile_url": "https://www.linkedin.com/in/jordanlee",
"provider_id": "urn:li:member:987654321"
},
"attachments": [],
"motion_id": "mot_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"enrollment_id": "enr_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"motion_name": "Q4 founders outreach",
"contact": {
"id": "con_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"linkedin_url": "https://www.linkedin.com/in/alexjordan",
"full_name": "Alex Jordan",
"first_name": "Alex",
"last_name": "Jordan",
"headline": "Head of Operations at Northwind",
"job_title": "Head of Operations",
"company": "Northwind",
"email": "alex@northwind.example",
"location": "Berlin, Germany",
"about": "Operations leader in logistics.",
"extra": {
"crm_id": "0035e00000AbCdE"
},
"tags": [
"in-conversation"
]
},
"occurred_at": "2026-05-28T14:28:00.000Z"
},
"delivered_at": "2026-05-28T14:28:01.345Z"
}chat.updated
A chat's container state changed (e.g. archived, muted, read-state); useful for inbox automation.
- Source:
messaging - Subscription: opt-in: name it in
events - Latency: Real time: seconds after LinkedIn reports it.
Subscribe with the CLI:
curviate webhook create --source messaging --events chat.updated --request-url https://hooks.example.com/curviateOr with the REST API:
curl -X POST https://api.curviate.com/v1/webhooks \
-H "Authorization: Bearer cvt_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"source": "messaging",
"request_url": "https://hooks.example.com/curviate",
"events": [
"chat.updated"
]
}'Example delivery:
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "chat.updated",
"data": {
"account_id": "acc_YOUR_ACCOUNT_ID",
"event": "chat.updated",
"chat_id": "chat_YOUR_CHAT_ID",
"occurred_at": "2026-05-28T14:30:00.000Z"
},
"delivered_at": "2026-05-28T14:30:01.000Z"
}chat.deleted
A chat thread was deleted.
- Source:
messaging - Subscription: opt-in: name it in
events - Latency: Real time: seconds after LinkedIn reports it.
Subscribe with the CLI:
curviate webhook create --source messaging --events chat.deleted --request-url https://hooks.example.com/curviateOr with the REST API:
curl -X POST https://api.curviate.com/v1/webhooks \
-H "Authorization: Bearer cvt_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"source": "messaging",
"request_url": "https://hooks.example.com/curviate",
"events": [
"chat.deleted"
]
}'Example delivery:
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "chat.deleted",
"data": {
"account_id": "acc_YOUR_ACCOUNT_ID",
"event": "chat.deleted",
"chat_id": "chat_YOUR_CHAT_ID",
"occurred_at": "2026-05-28T14:31:00.000Z"
},
"delivered_at": "2026-05-28T14:31:01.000Z"
}User events
connection.accepted
A pending invitation sent through Curviate (by a Motion or a direct send) was accepted by the recipient. Detected by Curviate's own polling, not real-time: latency up to about 160 in-window minutes while Motion invitations are pending, about 580 otherwise, longer while an account warms up.
- Source:
user - Subscription: default: subscribed when you omit
events - Latency: Not real time: about 2 hours after the acceptance (acceptances are polled).
Subscribe with the CLI:
curviate webhook create --source user --events connection.accepted --request-url https://hooks.example.com/curviateOr with the REST API:
curl -X POST https://api.curviate.com/v1/webhooks \
-H "Authorization: Bearer cvt_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"source": "user",
"request_url": "https://hooks.example.com/curviate",
"events": [
"connection.accepted"
]
}'Example delivery:
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "connection.accepted",
"data": {
"account_id": "acc_YOUR_ACCOUNT_ID",
"event": "connection.accepted",
"user": {
"full_name": "Alex Jordan",
"provider_id": "urn:li:member:123456789",
"public_identifier": "alexjordan",
"profile_url": "https://www.linkedin.com/in/alexjordan",
"picture_url": "https://media.licdn.com/dms/image/example/photo.jpg"
},
"motion_id": "mot_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"enrollment_id": "enr_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"motion_name": "Q4 founders outreach",
"contact": {
"id": "con_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"linkedin_url": "https://www.linkedin.com/in/alexjordan",
"full_name": "Alex Jordan",
"first_name": "Alex",
"last_name": "Jordan",
"headline": "Head of Operations at Northwind",
"job_title": "Head of Operations",
"company": "Northwind",
"email": "alex@northwind.example",
"location": "Berlin, Germany",
"about": "Operations leader in logistics.",
"extra": {
"crm_id": "0035e00000AbCdE"
},
"tags": [
"in-conversation"
]
},
"occurred_at": "2026-05-28T16:45:00.000Z"
},
"delivered_at": "2026-05-29T00:45:01.012Z"
}connection.new
A new relation appeared on the account (any new LinkedIn connection, not just ones you invited). Polled, not real-time; up to ~4h delay; a freshly connected account may see a backfill burst of these on first connect.
- Source:
user - Subscription: opt-in: name it in
events - Latency: Not real time: up to about 4 hours, and a backfill burst after a new connect.
Subscribe with the CLI:
curviate webhook create --source user --events connection.new --request-url https://hooks.example.com/curviateOr with the REST API:
curl -X POST https://api.curviate.com/v1/webhooks \
-H "Authorization: Bearer cvt_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"source": "user",
"request_url": "https://hooks.example.com/curviate",
"events": [
"connection.new"
]
}'Example delivery:
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "connection.new",
"data": {
"account_id": "acc_YOUR_ACCOUNT_ID",
"event": "connection.new",
"user": {
"full_name": "Sam Rivera",
"provider_id": "urn:li:member:246813579",
"public_identifier": "samrivera",
"profile_url": "https://www.linkedin.com/in/samrivera",
"picture_url": "https://media.licdn.com/dms/image/example/photo.jpg"
},
"occurred_at": "2026-05-28T18:00:00.000Z"
},
"delivered_at": "2026-05-28T22:00:01.500Z"
}Account status events
account.created
A new account link completed successfully for the first time (initial-connect path).
- Source:
account_status - Subscription: default: subscribed when you omit
events - Latency: Real time.
Subscribe with the CLI:
curviate webhook create --source account_status --events account.created --request-url https://hooks.example.com/curviateOr with the REST API:
curl -X POST https://api.curviate.com/v1/webhooks \
-H "Authorization: Bearer cvt_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"source": "account_status",
"request_url": "https://hooks.example.com/curviate",
"events": [
"account.created"
]
}'Example delivery:
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "account.created",
"data": {
"account_id": "acc_YOUR_ACCOUNT_ID",
"event": "account.created",
"status": "active",
"occurred_at": "2026-05-28T08:00:00.000Z"
},
"delivered_at": "2026-05-28T08:00:01.123Z"
}account.connected
The account is in a healthy, connected state. Also sent when a connect reactivates an account you had previously disconnected and it comes back healthy.
- Source:
account_status - Subscription: default: subscribed when you omit
events - Latency: Real time.
Subscribe with the CLI:
curviate webhook create --source account_status --events account.connected --request-url https://hooks.example.com/curviateOr with the REST API:
curl -X POST https://api.curviate.com/v1/webhooks \
-H "Authorization: Bearer cvt_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"source": "account_status",
"request_url": "https://hooks.example.com/curviate",
"events": [
"account.connected"
]
}'Example delivery:
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "account.connected",
"data": {
"account_id": "acc_YOUR_ACCOUNT_ID",
"event": "account.connected",
"status": "active",
"occurred_at": "2026-05-28T08:05:00.000Z"
},
"delivered_at": "2026-05-28T08:05:01.456Z"
}account.synced
A synchronization cycle completed successfully. No longer pushed in real time; v2 has no equivalent event; no read-path alternative exists.
- Source:
account_status - Subscription: default: subscribed when you omit
events - Latency: Not delivered any more: subscribing succeeds and nothing arrives. Read the account instead.
Subscribe with the CLI:
curviate webhook create --source account_status --events account.synced --request-url https://hooks.example.com/curviateOr with the REST API:
curl -X POST https://api.curviate.com/v1/webhooks \
-H "Authorization: Bearer cvt_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"source": "account_status",
"request_url": "https://hooks.example.com/curviate",
"events": [
"account.synced"
]
}'Example delivery:
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "account.synced",
"data": {
"account_id": "acc_YOUR_ACCOUNT_ID",
"event": "account.synced",
"status": "active",
"occurred_at": "2026-05-28T08:10:00.000Z"
},
"delivered_at": "2026-05-28T08:10:01.789Z"
}account.reconnected
An existing account was re-authorized in place (credentials refreshed). Reactivating an account you had previously disconnected does not send this event; that connect reports the state the account comes back in.
- Source:
account_status - Subscription: default: subscribed when you omit
events - Latency: Real time.
Subscribe with the CLI:
curviate webhook create --source account_status --events account.reconnected --request-url https://hooks.example.com/curviateOr with the REST API:
curl -X POST https://api.curviate.com/v1/webhooks \
-H "Authorization: Bearer cvt_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"source": "account_status",
"request_url": "https://hooks.example.com/curviate",
"events": [
"account.reconnected"
]
}'Example delivery:
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "account.reconnected",
"data": {
"account_id": "acc_YOUR_ACCOUNT_ID",
"event": "account.reconnected",
"status": "active",
"occurred_at": "2026-05-28T10:00:00.000Z"
},
"delivered_at": "2026-05-28T10:00:01.234Z"
}account.reconnect_needed
Credentials expired / cookie invalidated; the account needs reconnection.
- Source:
account_status - Subscription: default: subscribed when you omit
events - Latency: Real time.
Subscribe with the CLI:
curviate webhook create --source account_status --events account.reconnect_needed --request-url https://hooks.example.com/curviateOr with the REST API:
curl -X POST https://api.curviate.com/v1/webhooks \
-H "Authorization: Bearer cvt_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"source": "account_status",
"request_url": "https://hooks.example.com/curviate",
"events": [
"account.reconnect_needed"
]
}'Example delivery:
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "account.reconnect_needed",
"data": {
"account_id": "acc_YOUR_ACCOUNT_ID",
"event": "account.reconnect_needed",
"status": "reconnect_needed",
"occurred_at": "2026-05-28T11:30:00.000Z"
},
"delivered_at": "2026-05-28T11:30:01.567Z"
}account.restricted
The account is connected, but some actions on it fail: LinkedIn restricted the account, or one LinkedIn product on it (such as Sales Navigator or Recruiter) needs re-authentication or is failing. Surface it to a human. If a single product is failing, a reconnect may restore it. A LinkedIn restriction is usually detected by a daily account reconciliation (within about 24 hours) or immediately by a connect; a failing product is reported immediately. An on-demand account read always reports the current state.
- Source:
account_status - Subscription: default: subscribed when you omit
events - Latency: Not real time: a LinkedIn restriction is usually detected within about 24 hours; a failing product immediately.
Subscribe with the CLI:
curviate webhook create --source account_status --events account.restricted --request-url https://hooks.example.com/curviateOr with the REST API:
curl -X POST https://api.curviate.com/v1/webhooks \
-H "Authorization: Bearer cvt_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"source": "account_status",
"request_url": "https://hooks.example.com/curviate",
"events": [
"account.restricted"
]
}'Example delivery:
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "account.restricted",
"data": {
"account_id": "acc_YOUR_ACCOUNT_ID",
"event": "account.restricted",
"status": "restricted",
"occurred_at": "2026-05-28T13:30:00.000Z"
},
"delivered_at": "2026-05-28T13:30:01.204Z"
}account.creation_failed
The initial account-link attempt failed before completion (terminal; no account was established). No longer pushed in real time; detect via an on-demand account read.
- Source:
account_status - Subscription: default: subscribed when you omit
events - Latency: Not delivered any more: subscribing succeeds and nothing arrives. Read the account instead.
Subscribe with the CLI:
curviate webhook create --source account_status --events account.creation_failed --request-url https://hooks.example.com/curviateOr with the REST API:
curl -X POST https://api.curviate.com/v1/webhooks \
-H "Authorization: Bearer cvt_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"source": "account_status",
"request_url": "https://hooks.example.com/curviate",
"events": [
"account.creation_failed"
]
}'Example delivery:
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "account.creation_failed",
"data": {
"account_id": "acc_YOUR_ACCOUNT_ID",
"event": "account.creation_failed",
"status": "disconnected",
"occurred_at": "2026-05-28T07:55:00.000Z"
},
"delivered_at": "2026-05-28T07:55:01.345Z"
}account.disconnected
The account is in the disconnected state and cannot act until it is reconnected. This includes an explicit disconnect or deletion, and a connect or reconnect attempt that observes an already-disconnected account without removing it. Where the account was actually removed, its id will 404 on a later read.
- Source:
account_status - Subscription: default: subscribed when you omit
events - Latency: Real time.
Subscribe with the CLI:
curviate webhook create --source account_status --events account.disconnected --request-url https://hooks.example.com/curviateOr with the REST API:
curl -X POST https://api.curviate.com/v1/webhooks \
-H "Authorization: Bearer cvt_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"source": "account_status",
"request_url": "https://hooks.example.com/curviate",
"events": [
"account.disconnected"
]
}'Example delivery:
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "account.disconnected",
"data": {
"account_id": "acc_YOUR_ACCOUNT_ID",
"event": "account.disconnected",
"status": "disconnected",
"occurred_at": "2026-05-28T15:00:00.000Z"
},
"delivered_at": "2026-05-28T15:00:01.456Z"
}account.error
Account synchronization encountered an error (not a credentials issue; needs investigation).
- Source:
account_status - Subscription: default: subscribed when you omit
events - Latency: Real time.
Subscribe with the CLI:
curviate webhook create --source account_status --events account.error --request-url https://hooks.example.com/curviateOr with the REST API:
curl -X POST https://api.curviate.com/v1/webhooks \
-H "Authorization: Bearer cvt_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"source": "account_status",
"request_url": "https://hooks.example.com/curviate",
"events": [
"account.error"
]
}'Example delivery:
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "account.error",
"data": {
"account_id": "acc_YOUR_ACCOUNT_ID",
"event": "account.error",
"status": "reconnect_needed",
"occurred_at": "2026-05-28T12:00:00.000Z"
},
"delivered_at": "2026-05-28T12:00:01.890Z"
}account.paused
Account synchronization was stopped or paused externally. No longer pushed in real time; detect via an on-demand account read.
- Source:
account_status - Subscription: default: subscribed when you omit
events - Latency: Not delivered any more: subscribing succeeds and nothing arrives. Read the account instead.
Subscribe with the CLI:
curviate webhook create --source account_status --events account.paused --request-url https://hooks.example.com/curviateOr with the REST API:
curl -X POST https://api.curviate.com/v1/webhooks \
-H "Authorization: Bearer cvt_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"source": "account_status",
"request_url": "https://hooks.example.com/curviate",
"events": [
"account.paused"
]
}'Example delivery:
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "account.paused",
"data": {
"account_id": "acc_YOUR_ACCOUNT_ID",
"event": "account.paused",
"status": "reconnect_needed",
"occurred_at": "2026-05-28T13:00:00.000Z"
},
"delivered_at": "2026-05-28T13:00:01.012Z"
}account.connecting
An account link is in progress. Transient and high-frequency; opt in explicitly. The account is not yet active. No longer pushed in real time; v2 has no equivalent event.
- Source:
account_status - Subscription: default: subscribed when you omit
events - Latency: Not delivered any more: subscribing succeeds and nothing arrives. Read the account instead.
Subscribe with the CLI:
curviate webhook create --source account_status --events account.connecting --request-url https://hooks.example.com/curviateOr with the REST API:
curl -X POST https://api.curviate.com/v1/webhooks \
-H "Authorization: Bearer cvt_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"source": "account_status",
"request_url": "https://hooks.example.com/curviate",
"events": [
"account.connecting"
]
}'Example delivery:
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "account.connecting",
"data": {
"account_id": "acc_YOUR_ACCOUNT_ID",
"event": "account.connecting",
"status": "connecting",
"occurred_at": "2026-05-28T07:59:30.000Z"
},
"delivered_at": "2026-05-28T07:59:31.678Z"
}account.permission_revoked
A LinkedIn-side scope/permission the account relies on was withdrawn. No longer pushed in real time; detect via an on-demand account read.
- Source:
account_status - Subscription: default: subscribed when you omit
events - Latency: Not delivered any more: subscribing succeeds and nothing arrives. Read the account instead.
Subscribe with the CLI:
curviate webhook create --source account_status --events account.permission_revoked --request-url https://hooks.example.com/curviateOr with the REST API:
curl -X POST https://api.curviate.com/v1/webhooks \
-H "Authorization: Bearer cvt_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"source": "account_status",
"request_url": "https://hooks.example.com/curviate",
"events": [
"account.permission_revoked"
]
}'Example delivery:
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "account.permission_revoked",
"data": {
"account_id": "acc_YOUR_ACCOUNT_ID",
"event": "account.permission_revoked",
"status": "restricted",
"occurred_at": "2026-05-28T14:00:00.000Z"
},
"delivered_at": "2026-05-28T14:00:01.234Z"
}account.initial_sync.running
The initial history backfill for a newly connected account has started (informational; bracket-open).
- Source:
account_status - Subscription: opt-in: name it in
events - Latency: Real time.
Subscribe with the CLI:
curviate webhook create --source account_status --events account.initial_sync.running --request-url https://hooks.example.com/curviateOr with the REST API:
curl -X POST https://api.curviate.com/v1/webhooks \
-H "Authorization: Bearer cvt_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"source": "account_status",
"request_url": "https://hooks.example.com/curviate",
"events": [
"account.initial_sync.running"
]
}'Example delivery:
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "account.initial_sync.running",
"data": {
"status": "active",
"account_id": "acc_YOUR_ACCOUNT_ID",
"event": "account.initial_sync.running",
"occurred_at": "2026-05-28T08:00:00.000Z"
},
"delivered_at": "2026-05-28T08:00:01.000Z"
}account.initial_sync.completed
The initial history backfill completed; full LinkedIn history is now queryable.
- Source:
account_status - Subscription: opt-in: name it in
events - Latency: Real time.
Subscribe with the CLI:
curviate webhook create --source account_status --events account.initial_sync.completed --request-url https://hooks.example.com/curviateOr with the REST API:
curl -X POST https://api.curviate.com/v1/webhooks \
-H "Authorization: Bearer cvt_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"source": "account_status",
"request_url": "https://hooks.example.com/curviate",
"events": [
"account.initial_sync.completed"
]
}'Example delivery:
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "account.initial_sync.completed",
"data": {
"status": "active",
"account_id": "acc_YOUR_ACCOUNT_ID",
"event": "account.initial_sync.completed",
"occurred_at": "2026-05-28T08:12:00.000Z"
},
"delivered_at": "2026-05-28T08:12:01.000Z"
}account.initial_sync.failed
The initial history backfill failed. The delivered payload carries a neutral reason; one of internal, proxy, or provider.
- Source:
account_status - Subscription: opt-in: name it in
events - Latency: Real time.
Subscribe with the CLI:
curviate webhook create --source account_status --events account.initial_sync.failed --request-url https://hooks.example.com/curviateOr with the REST API:
curl -X POST https://api.curviate.com/v1/webhooks \
-H "Authorization: Bearer cvt_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"source": "account_status",
"request_url": "https://hooks.example.com/curviate",
"events": [
"account.initial_sync.failed"
]
}'Example delivery:
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "account.initial_sync.failed",
"data": {
"status": "active",
"reason": "provider",
"account_id": "acc_YOUR_ACCOUNT_ID",
"event": "account.initial_sync.failed",
"occurred_at": "2026-05-28T08:12:00.000Z"
},
"delivered_at": "2026-05-28T08:12:01.000Z"
}Post events
post.published
A scheduled post was published. The payload carries draft_id, post_id (null when the platform returned none), account_id, scheduled_at, published_at, and safety_warning when a warn-posture safety limit was breached. Never carries the post text or media.
- Source:
post - Subscription: default: subscribed when you omit
events - Latency: Real time: when the scheduled post fires.
Subscribe with the CLI:
curviate webhook create --source post --events post.published --request-url https://hooks.example.com/curviateOr with the REST API:
curl -X POST https://api.curviate.com/v1/webhooks \
-H "Authorization: Bearer cvt_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"source": "post",
"request_url": "https://hooks.example.com/curviate",
"events": [
"post.published"
]
}'Example delivery:
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "post.published",
"data": {
"account_id": "acc_YOUR_ACCOUNT_ID",
"event": "post.published",
"draft_id": "drf_YOUR_DRAFT_ID",
"post_id": "post_YOUR_POST_ID",
"scheduled_at": "2026-10-07T08:00:00.000Z",
"published_at": "2026-10-07T08:00:04.000Z"
},
"delivered_at": "2026-10-07T08:00:05.100Z"
}post.publish_failed
A scheduled post could not be published. The payload carries draft_id, account_id, scheduled_at, failure_code, and failure_message. Never carries the post text or media. A failure_code of outcome_unknown means the publish call timed out or ended without a usable answer after the request was sent; the post may be live, so check the account's posts before retrying.
- Source:
post - Subscription: default: subscribed when you omit
events - Latency: Real time: when the scheduled post fires.
Subscribe with the CLI:
curviate webhook create --source post --events post.publish_failed --request-url https://hooks.example.com/curviateOr with the REST API:
curl -X POST https://api.curviate.com/v1/webhooks \
-H "Authorization: Bearer cvt_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"source": "post",
"request_url": "https://hooks.example.com/curviate",
"events": [
"post.publish_failed"
]
}'Example delivery:
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "post.publish_failed",
"data": {
"account_id": "acc_YOUR_ACCOUNT_ID",
"event": "post.publish_failed",
"draft_id": "drf_YOUR_DRAFT_ID",
"scheduled_at": "2026-10-07T08:00:00.000Z",
"failure_code": "rate_limited",
"failure_message": "The account hit a platform rate limit."
},
"delivered_at": "2026-10-07T08:00:02.400Z"
}Motion events
motion.status_changed
A Motion changed status. Carries motion_id, motion_name, from, to, reason, reason_message and changed_by_user_id (null when Curviate made the change), with account_id null. Delivered once per webhook whose accounts overlap the Motion's sending accounts.
Carries no contact, and account_id is always null: it goes once to each webhook whose accounts overlap the Motion's sending accounts.
- Source:
motion - Subscription: default: subscribed when you omit
events - Latency: Real time: within seconds of the Motion's own step or transition.
Subscribe with the CLI:
curviate webhook create --source motion --events motion.status_changed --request-url https://hooks.example.com/curviateOr with the REST API:
curl -X POST https://api.curviate.com/v1/webhooks \
-H "Authorization: Bearer cvt_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"source": "motion",
"request_url": "https://hooks.example.com/curviate",
"events": [
"motion.status_changed"
]
}'Example delivery:
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "motion.status_changed",
"data": {
"motion_id": "mot_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"motion_name": "Q4 founders outreach",
"account_id": null,
"from": "active",
"to": "paused",
"reason": "paused_by_user",
"reason_message": null,
"changed_by_user_id": "usr_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"event": "motion.status_changed",
"occurred_at": "2026-10-21T10:41:12.000Z"
},
"delivered_at": "2026-10-21T10:41:13.020Z"
}enrollment.started
A Contact's Enrollment started. Carries account_id, account_name, account_profile_url, motion_id, motion_name, enrollment_id and contact (the Contact record, null once deleted), sequence_version and relationship_at_enrollment.
- Source:
motion - Subscription: default: subscribed when you omit
events - Latency: Real time: within seconds of the Motion's own step or transition.
Subscribe with the CLI:
curviate webhook create --source motion --events enrollment.started --request-url https://hooks.example.com/curviateOr with the REST API:
curl -X POST https://api.curviate.com/v1/webhooks \
-H "Authorization: Bearer cvt_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"source": "motion",
"request_url": "https://hooks.example.com/curviate",
"events": [
"enrollment.started"
]
}'Example delivery:
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "enrollment.started",
"data": {
"motion_id": "mot_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"motion_name": "Q4 founders outreach",
"enrollment_id": "enr_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"account_name": "Sam Rivera",
"account_profile_url": null,
"account_id": "acc_YOUR_ACCOUNT_ID",
"sequence_version": 3,
"relationship_at_enrollment": "not_connected",
"contact": {
"id": "con_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"linkedin_url": "https://www.linkedin.com/in/alexjordan",
"full_name": "Alex Jordan",
"first_name": "Alex",
"last_name": "Jordan",
"headline": "Head of Operations at Northwind",
"job_title": "Head of Operations",
"company": "Northwind",
"email": "alex@northwind.example",
"location": "Berlin, Germany",
"about": "Operations leader in logistics.",
"extra": {
"crm_id": "0035e00000AbCdE"
},
"tags": [
"in-conversation"
]
},
"event": "enrollment.started",
"occurred_at": "2026-10-21T10:41:12.000Z"
},
"delivered_at": "2026-10-21T10:41:13.020Z"
}enrollment.accepted
The Enrollment's invitation was accepted, once per Enrollment. Carries account_id, account_name, account_profile_url, motion_id, motion_name, enrollment_id and contact (the Contact record, null once deleted) and the invitation step's step_id, action and variant_id. connection.accepted (source user) fires for the same acceptance.
Fires once per Enrollment when its invitation is accepted, whatever the Enrollment's status. connection.accepted (source user) fires for the same acceptance; listen to either.
- Source:
motion - Subscription: default: subscribed when you omit
events - Latency: About 2 hours after the acceptance, like connection.accepted (acceptances are polled).
Subscribe with the CLI:
curviate webhook create --source motion --events enrollment.accepted --request-url https://hooks.example.com/curviateOr with the REST API:
curl -X POST https://api.curviate.com/v1/webhooks \
-H "Authorization: Bearer cvt_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"source": "motion",
"request_url": "https://hooks.example.com/curviate",
"events": [
"enrollment.accepted"
]
}'Example delivery:
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "enrollment.accepted",
"data": {
"motion_id": "mot_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"motion_name": "Q4 founders outreach",
"enrollment_id": "enr_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"account_name": "Sam Rivera",
"account_profile_url": null,
"account_id": "acc_YOUR_ACCOUNT_ID",
"step_id": "invite",
"action": "invite.send",
"variant_id": null,
"step_event": "invite_sent",
"contact": {
"id": "con_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"linkedin_url": "https://www.linkedin.com/in/alexjordan",
"full_name": "Alex Jordan",
"first_name": "Alex",
"last_name": "Jordan",
"headline": "Head of Operations at Northwind",
"job_title": "Head of Operations",
"company": "Northwind",
"email": "alex@northwind.example",
"location": "Berlin, Germany",
"about": "Operations leader in logistics.",
"extra": {
"crm_id": "0035e00000AbCdE"
},
"tags": [
"in-conversation"
]
},
"event": "enrollment.accepted",
"occurred_at": "2026-10-21T10:41:12.000Z"
},
"delivered_at": "2026-10-21T10:41:13.020Z"
}enrollment.replied
The Contact replied for the first time on this Enrollment, once per Enrollment. Carries account_id, account_name, account_profile_url, motion_id, motion_name, enrollment_id and contact (the Contact record, null once deleted), the latest messaging step's step_id, action and variant_id, the reply's chat_id and message_id, and reply_text (the text the Contact sent).
Fires once per Enrollment, on the Contact's first reply, whatever stop_on_engagement says; when the Motion stops on engagement it arrives before enrollment.finished. reply_text is the text the Contact sent. The text Curviate sent is never in a payload: step_id and variant_id say which copy went out. Needs inbox access to the account at delivery.
- Source:
motion - Subscription: default: subscribed when you omit
events - Latency: Real time: seconds after the reply reaches the account.
Subscribe with the CLI:
curviate webhook create --source motion --events enrollment.replied --request-url https://hooks.example.com/curviateOr with the REST API:
curl -X POST https://api.curviate.com/v1/webhooks \
-H "Authorization: Bearer cvt_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"source": "motion",
"request_url": "https://hooks.example.com/curviate",
"events": [
"enrollment.replied"
]
}'Example delivery:
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "enrollment.replied",
"data": {
"motion_id": "mot_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"motion_name": "Q4 founders outreach",
"enrollment_id": "enr_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"account_name": "Sam Rivera",
"account_profile_url": null,
"account_id": "acc_YOUR_ACCOUNT_ID",
"step_id": "dm1",
"action": "message.send",
"variant_id": "a",
"step_event": null,
"chat_id": "chat_YOUR_CHAT_ID",
"message_id": "msg_YOUR_REPLY_ID",
"reply_text": "Thanks, happy to talk next week.",
"contact": {
"id": "con_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"linkedin_url": "https://www.linkedin.com/in/alexjordan",
"full_name": "Alex Jordan",
"first_name": "Alex",
"last_name": "Jordan",
"headline": "Head of Operations at Northwind",
"job_title": "Head of Operations",
"company": "Northwind",
"email": "alex@northwind.example",
"location": "Berlin, Germany",
"about": "Operations leader in logistics.",
"extra": {
"crm_id": "0035e00000AbCdE"
},
"tags": [
"in-conversation"
]
},
"event": "enrollment.replied",
"occurred_at": "2026-10-21T10:41:12.000Z"
},
"delivered_at": "2026-10-21T10:41:13.020Z"
}enrollment.seen
A Motion message's read receipt arrived, once per message. Opt-in. Carries account_id, account_name, account_profile_url, motion_id, motion_name, enrollment_id and contact (the Contact record, null once deleted), the message step's step_id, action and variant_id, chat_id and seen_recorded_at (when the receipt arrived, not when it was read).
Fires once per Motion message whose read receipt arrives. seen_recorded_at is when the receipt arrived, not when the person read it.
- Source:
motion - Subscription: opt-in: name it in
events - Latency: When the read receipt reaches the account; never for recipients who turned receipts off.
Subscribe with the CLI:
curviate webhook create --source motion --events enrollment.seen --request-url https://hooks.example.com/curviateOr with the REST API:
curl -X POST https://api.curviate.com/v1/webhooks \
-H "Authorization: Bearer cvt_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"source": "motion",
"request_url": "https://hooks.example.com/curviate",
"events": [
"enrollment.seen"
]
}'Example delivery:
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "enrollment.seen",
"data": {
"motion_id": "mot_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"motion_name": "Q4 founders outreach",
"enrollment_id": "enr_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"account_name": "Sam Rivera",
"account_profile_url": null,
"account_id": "acc_YOUR_ACCOUNT_ID",
"step_id": "dm1",
"action": "message.send",
"variant_id": "a",
"step_event": null,
"chat_id": "chat_YOUR_CHAT_ID",
"message_id": "msg_YOUR_MESSAGE_ID",
"seen_recorded_at": "2026-10-21T10:42:00.000Z",
"contact": {
"id": "con_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"linkedin_url": "https://www.linkedin.com/in/alexjordan",
"full_name": "Alex Jordan",
"first_name": "Alex",
"last_name": "Jordan",
"headline": "Head of Operations at Northwind",
"job_title": "Head of Operations",
"company": "Northwind",
"email": "alex@northwind.example",
"location": "Berlin, Germany",
"about": "Operations leader in logistics.",
"extra": {
"crm_id": "0035e00000AbCdE"
},
"tags": [
"in-conversation"
]
},
"event": "enrollment.seen",
"occurred_at": "2026-10-21T10:41:12.000Z"
},
"delivered_at": "2026-10-21T10:41:13.020Z"
}enrollment.reassigned
An Enrollment moved to another sending account. Opt-in. Carries account_id, account_name, account_profile_url, motion_id, motion_name, enrollment_id and contact (the Contact record, null once deleted) of the new account, from_account_id, to_account_id and changed_by_user_id.
Fires when someone moves an Enrollment to another sending account. The account keys name the new account.
- Source:
motion - Subscription: opt-in: name it in
events - Latency: Real time: within seconds of the Motion's own step or transition.
Subscribe with the CLI:
curviate webhook create --source motion --events enrollment.reassigned --request-url https://hooks.example.com/curviateOr with the REST API:
curl -X POST https://api.curviate.com/v1/webhooks \
-H "Authorization: Bearer cvt_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"source": "motion",
"request_url": "https://hooks.example.com/curviate",
"events": [
"enrollment.reassigned"
]
}'Example delivery:
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "enrollment.reassigned",
"data": {
"motion_id": "mot_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"motion_name": "Q4 founders outreach",
"enrollment_id": "enr_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"account_name": "Sam Rivera",
"account_profile_url": null,
"account_id": "acc_NEW_ACCOUNT_ID",
"from_account_id": "acc_YOUR_ACCOUNT_ID",
"to_account_id": "acc_NEW_ACCOUNT_ID",
"changed_by_user_id": "usr_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"contact": {
"id": "con_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"linkedin_url": "https://www.linkedin.com/in/alexjordan",
"full_name": "Alex Jordan",
"first_name": "Alex",
"last_name": "Jordan",
"headline": "Head of Operations at Northwind",
"job_title": "Head of Operations",
"company": "Northwind",
"email": "alex@northwind.example",
"location": "Berlin, Germany",
"about": "Operations leader in logistics.",
"extra": {
"crm_id": "0035e00000AbCdE"
},
"tags": [
"in-conversation"
]
},
"event": "enrollment.reassigned",
"occurred_at": "2026-10-21T10:41:12.000Z"
},
"delivered_at": "2026-10-21T10:41:13.020Z"
}enrollment.skipped
A Contact was not enrolled. Carries account_id (null when no account was assigned yet; then delivered once per webhook whose accounts overlap the Motion's), account_name, account_profile_url, motion_id, motion_name, enrollment_id, reason, reason_message, detail and contact.
- Source:
motion - Subscription: default: subscribed when you omit
events - Latency: Real time: within seconds of the Motion's own step or transition.
Subscribe with the CLI:
curviate webhook create --source motion --events enrollment.skipped --request-url https://hooks.example.com/curviateOr with the REST API:
curl -X POST https://api.curviate.com/v1/webhooks \
-H "Authorization: Bearer cvt_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"source": "motion",
"request_url": "https://hooks.example.com/curviate",
"events": [
"enrollment.skipped"
]
}'Example delivery:
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "enrollment.skipped",
"data": {
"motion_id": "mot_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"motion_name": "Q4 founders outreach",
"enrollment_id": "enr_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"account_name": "Sam Rivera",
"account_profile_url": null,
"account_id": "acc_YOUR_ACCOUNT_ID",
"reason": "in_exclusion_list",
"reason_message": "The Contact is on one of the Motion's exclusion lists, so it was not enrolled.",
"detail": null,
"contact": {
"id": "con_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"linkedin_url": "https://www.linkedin.com/in/alexjordan",
"full_name": "Alex Jordan",
"first_name": "Alex",
"last_name": "Jordan",
"headline": "Head of Operations at Northwind",
"job_title": "Head of Operations",
"company": "Northwind",
"email": "alex@northwind.example",
"location": "Berlin, Germany",
"about": "Operations leader in logistics.",
"extra": {
"crm_id": "0035e00000AbCdE"
},
"tags": [
"in-conversation"
]
},
"event": "enrollment.skipped",
"occurred_at": "2026-10-21T10:41:12.000Z"
},
"delivered_at": "2026-10-21T10:41:13.020Z"
}enrollment.finished
An Enrollment ended. Carries account_id, account_name, account_profile_url, motion_id, motion_name, enrollment_id and contact (the Contact record, null once deleted), reason (for example completed, stopped, removed, replied, messaged_manually, contact_deleted), reason_message, replied and last_step_id.
- Source:
motion - Subscription: default: subscribed when you omit
events - Latency: Real time: within seconds of the Motion's own step or transition.
Subscribe with the CLI:
curviate webhook create --source motion --events enrollment.finished --request-url https://hooks.example.com/curviateOr with the REST API:
curl -X POST https://api.curviate.com/v1/webhooks \
-H "Authorization: Bearer cvt_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"source": "motion",
"request_url": "https://hooks.example.com/curviate",
"events": [
"enrollment.finished"
]
}'Example delivery:
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "enrollment.finished",
"data": {
"motion_id": "mot_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"motion_name": "Q4 founders outreach",
"enrollment_id": "enr_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"account_name": "Sam Rivera",
"account_profile_url": null,
"account_id": "acc_YOUR_ACCOUNT_ID",
"reason": "replied",
"reason_message": "The person replied and the Motion stops on engagement, so the Enrollment ended.",
"replied": true,
"last_step_id": "wait_reply",
"contact": {
"id": "con_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"linkedin_url": "https://www.linkedin.com/in/alexjordan",
"full_name": "Alex Jordan",
"first_name": "Alex",
"last_name": "Jordan",
"headline": "Head of Operations at Northwind",
"job_title": "Head of Operations",
"company": "Northwind",
"email": "alex@northwind.example",
"location": "Berlin, Germany",
"about": "Operations leader in logistics.",
"extra": {
"crm_id": "0035e00000AbCdE"
},
"tags": [
"in-conversation"
]
},
"event": "enrollment.finished",
"occurred_at": "2026-10-21T10:41:12.000Z"
},
"delivered_at": "2026-10-21T10:41:13.020Z"
}step.executed
A Step ran. Opt-in because of its volume. Carries account_id, account_name, account_profile_url, motion_id, motion_name, enrollment_id and contact (the Contact record, null once deleted), step_id, action, variant_id, used_fallback, step_event (the step's custom event name or null), and chat_id and message_id for a message, or post_url for a post action. Never the text that was sent.
- Source:
motion - Subscription: opt-in: name it in
events - Latency: Real time: within seconds of the Motion's own step or transition.
Subscribe with the CLI:
curviate webhook create --source motion --events step.executed --request-url https://hooks.example.com/curviateOr with the REST API:
curl -X POST https://api.curviate.com/v1/webhooks \
-H "Authorization: Bearer cvt_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"source": "motion",
"request_url": "https://hooks.example.com/curviate",
"events": [
"step.executed"
]
}'Example delivery:
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "step.executed",
"data": {
"motion_id": "mot_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"motion_name": "Q4 founders outreach",
"enrollment_id": "enr_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"account_name": "Sam Rivera",
"account_profile_url": null,
"account_id": "acc_YOUR_ACCOUNT_ID",
"step_id": "dm1",
"action": "message.send",
"variant_id": "a",
"step_event": "first_message_sent",
"used_fallback": false,
"chat_id": "chat_YOUR_CHAT_ID",
"message_id": "msg_YOUR_MESSAGE_ID",
"contact": {
"id": "con_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"linkedin_url": "https://www.linkedin.com/in/alexjordan",
"full_name": "Alex Jordan",
"first_name": "Alex",
"last_name": "Jordan",
"headline": "Head of Operations at Northwind",
"job_title": "Head of Operations",
"company": "Northwind",
"email": "alex@northwind.example",
"location": "Berlin, Germany",
"about": "Operations leader in logistics.",
"extra": {
"crm_id": "0035e00000AbCdE"
},
"tags": [
"in-conversation"
]
},
"event": "step.executed",
"occurred_at": "2026-10-21T10:41:12.000Z"
},
"delivered_at": "2026-10-21T10:41:13.020Z"
}A post action (post.react, post.comment) carries post_url instead of chat_id and message_id:
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "step.executed",
"data": {
"motion_id": "mot_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"motion_name": "Q4 founders outreach",
"enrollment_id": "enr_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"account_name": "Sam Rivera",
"account_profile_url": null,
"account_id": "acc_YOUR_ACCOUNT_ID",
"step_id": "react",
"action": "post.react",
"variant_id": null,
"step_event": null,
"used_fallback": false,
"contact": {
"id": "con_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"linkedin_url": "https://www.linkedin.com/in/alexjordan",
"full_name": "Alex Jordan",
"first_name": "Alex",
"last_name": "Jordan",
"headline": "Head of Operations at Northwind",
"job_title": "Head of Operations",
"company": "Northwind",
"email": "alex@northwind.example",
"location": "Berlin, Germany",
"about": "Operations leader in logistics.",
"extra": {
"crm_id": "0035e00000AbCdE"
},
"tags": [
"in-conversation"
]
},
"event": "step.executed",
"occurred_at": "2026-10-21T10:41:12.000Z",
"post_url": "https://www.linkedin.com/feed/update/urn:li:activity:7254000000000000000"
},
"delivered_at": "2026-10-21T10:41:13.020Z"
}step.failed
A Step was skipped or failed. Carries account_id, account_name, account_profile_url, motion_id, motion_name, enrollment_id and contact (the Contact record, null once deleted), step_id, action, variant_id, step_event, outcome (skipped or failed), reason and reason_message.
- Source:
motion - Subscription: default: subscribed when you omit
events - Latency: Real time: within seconds of the Motion's own step or transition.
Subscribe with the CLI:
curviate webhook create --source motion --events step.failed --request-url https://hooks.example.com/curviateOr with the REST API:
curl -X POST https://api.curviate.com/v1/webhooks \
-H "Authorization: Bearer cvt_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"source": "motion",
"request_url": "https://hooks.example.com/curviate",
"events": [
"step.failed"
]
}'Example delivery:
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "step.failed",
"data": {
"motion_id": "mot_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"motion_name": "Q4 founders outreach",
"enrollment_id": "enr_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"account_name": "Sam Rivera",
"account_profile_url": null,
"account_id": "acc_YOUR_ACCOUNT_ID",
"step_id": "invite",
"action": "invite.send",
"variant_id": null,
"step_event": "invite_sent",
"outcome": "skipped",
"reason": "already_connected",
"reason_message": "Already connected to this Account, so no invitation was sent.",
"contact": {
"id": "con_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"linkedin_url": "https://www.linkedin.com/in/alexjordan",
"full_name": "Alex Jordan",
"first_name": "Alex",
"last_name": "Jordan",
"headline": "Head of Operations at Northwind",
"job_title": "Head of Operations",
"company": "Northwind",
"email": "alex@northwind.example",
"location": "Berlin, Germany",
"about": "Operations leader in logistics.",
"extra": {
"crm_id": "0035e00000AbCdE"
},
"tags": [
"in-conversation"
]
},
"event": "step.failed",
"occurred_at": "2026-10-21T10:41:12.000Z"
},
"delivered_at": "2026-10-21T10:41:13.020Z"
}motion.custom_event
A step that ran named a custom event (its event key, or a legacy emit step). Carries name, step_id, account_id, account_name, account_profile_url, motion_id, motion_name, enrollment_id and contact (the Contact record, null once deleted). Was motion.signal: a webhook subscribed to motion.signal receives it under that name until 2027-01-19.
Fires once when a step that carries an event ran (a do step that executed, a tag step taken), or when a legacy emit step is reached; never for a skipped or failed step. An event an agent sends to an Enrollment (POST /v1/enrollments/{id}/events) is an input only and fires no webhook. It was called motion.signal: a webhook subscribed to motion.signal keeps receiving it under that name, with the same data, until 2027-01-19.
- Source:
motion - Subscription: default: subscribed when you omit
events - Latency: Real time: within seconds of the Motion's own step or transition.
Subscribe with the CLI:
curviate webhook create --source motion --events motion.custom_event --request-url https://hooks.example.com/curviateOr with the REST API:
curl -X POST https://api.curviate.com/v1/webhooks \
-H "Authorization: Bearer cvt_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"source": "motion",
"request_url": "https://hooks.example.com/curviate",
"events": [
"motion.custom_event"
]
}'Example delivery:
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "motion.custom_event",
"data": {
"name": "no_reply_7d",
"motion_id": "mot_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"motion_name": "Q4 founders outreach",
"enrollment_id": "enr_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"account_name": "Sam Rivera",
"account_profile_url": null,
"account_id": "acc_YOUR_ACCOUNT_ID",
"step_id": "no_reply",
"action": null,
"variant_id": null,
"step_event": "no_reply_7d",
"contact": {
"id": "con_01J8Z3K9P0Q1R2S3T4V5W6X7Y8",
"linkedin_url": "https://www.linkedin.com/in/alexjordan",
"full_name": "Alex Jordan",
"first_name": "Alex",
"last_name": "Jordan",
"headline": "Head of Operations at Northwind",
"job_title": "Head of Operations",
"company": "Northwind",
"email": "alex@northwind.example",
"location": "Berlin, Germany",
"about": "Operations leader in logistics.",
"extra": {
"crm_id": "0035e00000AbCdE"
},
"tags": [
"in-conversation"
]
},
"event": "motion.custom_event",
"occurred_at": "2026-10-21T10:41:12.000Z"
},
"delivered_at": "2026-10-21T10:41:13.020Z"
}Recruiter events
recruiter.applicant.added
A candidate or applicant was added to a hiring project pipeline.
- Source:
recruiter - Subscription: not subscribable yet (a webhook with this source is refused with
400 INVALID_REQUEST) - Latency: Not delivered yet: listed in the catalogue for completeness.
Check it in the catalogue with the CLI:
curviate webhook events --jsonOr with the REST API:
curl https://api.curviate.com/v1/webhooks/events \
-H "Authorization: Bearer cvt_live_YOUR_API_KEY"Example delivery:
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "recruiter.applicant.added",
"data": {
"account_id": "acc_YOUR_ACCOUNT_ID",
"project_id": "prj_YOUR_PROJECT_ID",
"candidate_id": "cnd_YOUR_CANDIDATE_ID",
"event": "recruiter.applicant.added",
"occurred_at": "2026-10-21T10:41:12.000Z"
},
"delivered_at": "2026-10-21T10:41:13.020Z"
}recruiter.project.candidate_status_changed
A candidate's status in a hiring project pipeline changed (e.g. rejected).
- Source:
recruiter - Subscription: not subscribable yet (a webhook with this source is refused with
400 INVALID_REQUEST) - Latency: Not delivered yet: listed in the catalogue for completeness.
Check it in the catalogue with the CLI:
curviate webhook events --jsonOr with the REST API:
curl https://api.curviate.com/v1/webhooks/events \
-H "Authorization: Bearer cvt_live_YOUR_API_KEY"Example delivery:
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "recruiter.project.candidate_status_changed",
"data": {
"account_id": "acc_YOUR_ACCOUNT_ID",
"project_id": "prj_YOUR_PROJECT_ID",
"candidate_id": "cnd_YOUR_CANDIDATE_ID",
"status": "rejected",
"event": "recruiter.project.candidate_status_changed",
"occurred_at": "2026-10-21T10:41:12.000Z"
},
"delivered_at": "2026-10-21T10:41:13.020Z"
}Sales Navigator events
sales_nav.inmail.received
An InMail arrived on a Sales Navigator seat.
- Source:
sales_nav - Subscription: not subscribable yet (a webhook with this source is refused with
400 INVALID_REQUEST) - Latency: Not delivered yet: listed in the catalogue for completeness.
Check it in the catalogue with the CLI:
curviate webhook events --jsonOr with the REST API:
curl https://api.curviate.com/v1/webhooks/events \
-H "Authorization: Bearer cvt_live_YOUR_API_KEY"Example delivery:
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "sales_nav.inmail.received",
"data": {
"account_id": "acc_YOUR_ACCOUNT_ID",
"chat_id": "chat_YOUR_CHAT_ID",
"message_id": "msg_YOUR_MESSAGE_ID",
"text": "Hello from Sales Navigator.",
"event": "sales_nav.inmail.received",
"occurred_at": "2026-10-21T10:41:12.000Z"
},
"delivered_at": "2026-10-21T10:41:13.020Z"
}