Account status events
Fourteen events that track the full lifecycle of a connected LinkedIn account — creation, sync, authentication changes, errors, removal, and initial history backfill.
Quick reference
The Availability column marks how each event is delivered. Events with no marker are
delivered in real time; four legacy events are no_longer_realtime (not delivered on
the current platform) — see the callouts below.
| Event | Availability | Description |
|---|---|---|
account.created | Real-time | A new account link completed successfully for the first time. |
account.connected | Real-time | A LinkedIn account is in a healthy, connected state. |
account.synced | no_longer_realtime | A synchronization cycle completed successfully. |
account.reconnected | Real-time | An account was re-authorized in place — credentials refreshed. |
account.reconnect_needed | Real-time | Credentials expired — the account requires re-authentication. |
account.creation_failed | no_longer_realtime | The initial account-link attempt failed before completion. |
account.disconnected | Real-time | The account was removed from the workspace (terminal state). |
account.paused | Real-time | Account synchronization was stopped or paused externally. |
account.error | Real-time | Account synchronization halted due to an error — action required. |
account.connecting | no_longer_realtime | An account connection flow is in progress (transient, high-frequency). |
account.permission_revoked | no_longer_realtime | Required LinkedIn permissions were withdrawn from the account. |
account.initial_sync.running | Real-time · opt-in | The initial history backfill started (informational — bracket open). |
account.initial_sync.completed | Real-time · opt-in | The initial history backfill completed — full LinkedIn history is now queryable. |
account.initial_sync.failed | Real-time · opt-in | The initial history backfill failed — the delivery carries a neutral reason. |
Subscribe to all or a subset when creating your webhook:
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",
"account_ids": ["acc_YOUR_ACCOUNT_ID"]
}'Omitting events subscribes to the 11 lifecycle events by default. The three
account.initial_sync.* events are opt-in — name them explicitly in events[] to
receive them.
account.synced, account.creation_failed,
account.connecting, and account.permission_revoked carry
availability: "no_longer_realtime" — they are not delivered
on the current platform. For account.creation_failed and
account.permission_revoked, detect the state via an on-demand account
read (GET /v1/accounts/{account_id}). For
account.synced and account.connecting there is no
equivalent event and no direct read-path signal. This is honest deprecation, not a
bug.
On each account connect, the initial history backfill is bracketed by a bounded
2-event sequence: exactly one account.initial_sync.running (bracket
open, informational), followed by exactly one of
account.initial_sync.completed or
account.initial_sync.failed. account.initial_sync.completed
is the actionable signal — the account's full LinkedIn history is now queryable.
These three events are opt-in.
account.connecting was historically a transient, high-frequency event
fired while a link was in progress. Today it carries
availability: "no_longer_realtime" and is not delivered — do not build
on receiving it. Detect link-in-progress via the account read
(GET /v1/accounts/{account_id}) instead.
Connection lifecycle
account.created
Fired when a new account link completes successfully for the first time — the initial connect path. Use this event to start any post-onboarding logic in your agent.
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "account.created",
"data": {
"account_id": "acc_YOUR_ACCOUNT_ID",
"status": "account.created",
"occurred_at": "2026-05-28T08:00:00.000Z"
},
"delivered_at": "2026-05-28T08:00:01.123Z"
}account.connected
Fired when a health check confirms the account is in a healthy, connected state.
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "account.connected",
"data": {
"account_id": "acc_YOUR_ACCOUNT_ID",
"status": "account.connected",
"occurred_at": "2026-05-28T08:05:00.000Z"
},
"delivered_at": "2026-05-28T08:05:01.456Z"
}account.reconnected
Fired when an account that previously required re-authentication is back online — credentials refreshed in place without creating a new account ID.
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "account.reconnected",
"data": {
"account_id": "acc_YOUR_ACCOUNT_ID",
"status": "account.reconnected",
"occurred_at": "2026-05-28T10:00:00.000Z"
},
"delivered_at": "2026-05-28T10:00:01.234Z"
}account.reconnect_needed
Fired when the account's session expires or its credentials become invalid. The
account remains in the workspace but is inactive until the user completes
re-authentication. Trigger a reconnect flow from the dashboard or call
POST /v1/auth/intent with the account's account_id in the body to
re-authenticate it in place.
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "account.reconnect_needed",
"data": {
"account_id": "acc_YOUR_ACCOUNT_ID",
"status": "account.reconnect_needed",
"occurred_at": "2026-05-28T11:30:00.000Z"
},
"delivered_at": "2026-05-28T11:30:01.567Z"
}Sync states
account.synced · no_longer_realtime
Historically fired when a synchronization cycle completed successfully. It now carries
availability: "no_longer_realtime" and is not delivered on the current platform —
there is no equivalent event and no read-path signal. Do not build on it. The shape it
carried is shown below for reference:
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "account.synced",
"data": {
"account_id": "acc_YOUR_ACCOUNT_ID",
"status": "account.synced",
"occurred_at": "2026-05-28T08:10:00.000Z"
},
"delivered_at": "2026-05-28T08:10:01.789Z"
}Error and pause states
These are distinct states.
account.error means synchronization halted due to an error — action
is required to restore the account.
account.paused means synchronization was intentionally stopped or
paused — a deliberate state, not a failure condition. Your handler should treat
them differently: account.error warrants an alert or automated
reconnect attempt; account.paused is expected and requires no
immediate action.
account.error
Fired when account synchronization halted due to an error. Action is required to restore the account — check the dashboard for details and consider triggering a reconnect flow.
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "account.error",
"data": {
"account_id": "acc_YOUR_ACCOUNT_ID",
"status": "account.error",
"occurred_at": "2026-05-28T12:00:00.000Z"
},
"delivered_at": "2026-05-28T12:00:01.890Z"
}account.paused
Fired when account synchronization was intentionally paused — a deliberate, non-error state. No immediate action is required.
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "account.paused",
"data": {
"account_id": "acc_YOUR_ACCOUNT_ID",
"status": "account.paused",
"occurred_at": "2026-05-28T13:00:00.000Z"
},
"delivered_at": "2026-05-28T13:00:01.012Z"
}account.permission_revoked · no_longer_realtime
A LinkedIn-side scope or permission the account relies on was withdrawn; the account
may require re-authorization to restore access. This event carries
availability: "no_longer_realtime" and is not delivered on the current platform —
detect the state via an on-demand account read (GET /v1/accounts/{account_id}). The
shape it carried:
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "account.permission_revoked",
"data": {
"account_id": "acc_YOUR_ACCOUNT_ID",
"status": "account.permission_revoked",
"occurred_at": "2026-05-28T14:00:00.000Z"
},
"delivered_at": "2026-05-28T14:00:01.234Z"
}Terminal states
account.creation_failed · no_longer_realtime
The initial account-link attempt failed before completion — terminal, and no account
was established for operational use. This event carries
availability: "no_longer_realtime" and is not delivered on the current platform —
detect the outcome via an on-demand account read (GET /v1/accounts/{account_id}). The
shape it carried:
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "account.creation_failed",
"data": {
"account_id": "acc_YOUR_ACCOUNT_ID",
"status": "account.creation_failed",
"occurred_at": "2026-05-28T07:55:00.000Z"
},
"delivered_at": "2026-05-28T07:55:01.345Z"
}account.disconnected
Fired when an account is permanently removed from the workspace — via the dashboard,
the DELETE /v1/accounts/{id} API, or an explicit disconnect. This is a terminal
state. The account ID is no longer valid and any webhooks scoped to it will stop
delivering.
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "account.disconnected",
"data": {
"account_id": "acc_YOUR_ACCOUNT_ID",
"status": "account.disconnected",
"occurred_at": "2026-05-28T15:00:00.000Z"
},
"delivered_at": "2026-05-28T15:00:01.456Z"
}In-progress state
account.connecting · no_longer_realtime
Historically a transient, high-frequency event fired while an account connection flow
was in progress. It now carries availability: "no_longer_realtime" and is not
delivered on the current platform, and there is no equivalent event — do not build on
receiving it. Detect link-in-progress via the account read
(GET /v1/accounts/{account_id}), and wait for account.created or account.connected
as the completion signal. The shape it carried:
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "account.connecting",
"data": {
"account_id": "acc_YOUR_ACCOUNT_ID",
"status": "account.connecting",
"occurred_at": "2026-05-28T07:59:30.000Z"
},
"delivered_at": "2026-05-28T07:59:31.678Z"
}Initial sync
The initial history backfill for a newly connected account is reported by three
opt-in events that form a bounded bracket — exactly one
account.initial_sync.running, followed by exactly one of
account.initial_sync.completed or account.initial_sync.failed. Name them in
events[] to receive them.
account.initial_sync.running
The initial history backfill has started — informational, bracket open.
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "account.initial_sync.running",
"data": {
"account_id": "acc_YOUR_ACCOUNT_ID",
"timestamp": "2026-05-28T08:00:00.000Z"
},
"delivered_at": "2026-05-28T08:00:01.000Z"
}account.initial_sync.completed
The initial history backfill completed — the actionable signal. The account's full LinkedIn history is now queryable.
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "account.initial_sync.completed",
"data": {
"account_id": "acc_YOUR_ACCOUNT_ID",
"timestamp": "2026-05-28T08:12:00.000Z"
},
"delivered_at": "2026-05-28T08:12:01.000Z"
}account.initial_sync.failed
The initial history backfill failed. The delivery carries a neutral reason whose
value is exactly one of internal, proxy, or provider.
{
"id": "wdl_YOUR_DELIVERY_ID",
"webhook_id": "wh_YOUR_WEBHOOK_ID",
"event": "account.initial_sync.failed",
"data": {
"account_id": "acc_YOUR_ACCOUNT_ID",
"timestamp": "2026-05-28T08:12:00.000Z",
"reason": "provider"
},
"delivered_at": "2026-05-28T08:12:01.000Z"
}On account.initial_sync.failed, reason is exactly one of
internal, proxy, or provider. Treat it as a
closed set — no other value is delivered.
Delivery payload
Account status carries two data shapes. data.account_id is always present on both.
Lifecycle events (the 11) carry { account_id, status, occurred_at }:
{
"account_id": "acc_YOUR_ACCOUNT_ID",
"status": "account.reconnect_needed",
"occurred_at": "2026-05-28T11:30:00.000Z"
}account_id— theacc_…ID of the affected account in your workspace.status— the canonical event type string (e.g."account.reconnect_needed"). Always a stable Curviate canonical name — never a raw internal token.occurred_at— when the state transition occurred.
account.initial_sync.* events (the 3) carry { account_id, timestamp } for
running and completed, and { account_id, timestamp, reason } for failed:
{
"account_id": "acc_YOUR_ACCOUNT_ID",
"timestamp": "2026-05-28T08:12:00.000Z",
"reason": "provider"
}Account status events carry structural state metadata only — no LinkedIn message
content, profile text, or attachment data. There is no data[] field remapping
available for this source.