Webhooks
Receive LinkedIn event notifications — messages received, connections accepted, accounts connected — delivered as signed HTTP POST callbacks to your server. Messaging and account-lifecycle events arrive in near-real-time; connection events are delivered on a poll delay.
curl -X POST https://api.curviate.com/v1/webhooks \
-H "Authorization: Bearer cvt_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "My message webhook",
"source": "messaging",
"request_url": "https://hooks.example.com/curviate",
"account_ids": ["acc_YOUR_ACCOUNT_ID"],
"events": ["message.received", "message.read"]
}'Each webhook subscribes to a single event source (messaging, user, or
account_status), and every event in events must belong to that source. To
receive events from more than one source, create one webhook per source.
The response includes a one-time secret — your HMAC signing key for verifying every
incoming delivery. Copy it immediately.
{
"object": "webhook",
"id": "wh_01JR8M5KXYZ0000000001",
"source": "messaging",
"request_url": "https://hooks.example.com/curviate",
"account_ids": ["acc_YOUR_ACCOUNT_ID"],
"events": ["message.received", "message.read"],
"format": "json",
"enabled": true,
"secret": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6",
"secret_prefix": "a1b2c3d4",
"created_at": "2026-05-28T08:00:00.000Z"
}The secret is returned exactly once and is never retrievable
again. Store it as CURVIATE_WEBHOOK_SECRET in your environment
before discarding this response. The dashboard shows only the 8-character
prefix (a1b2c3d4...) for identification.
How webhooks work
When a LinkedIn event occurs on a connected account in your workspace, Curviate
dispatches an HTTP POST to every registered URL subscribed to that event type.
Each delivery carries:
- A JSON body with the event name, a delivery ID, and event data. Content events —
messaging events include the full message content (
text,sender, attachment metadata) and connection events carry the new contact's profile fields. Structural events — the account-status lifecycle events and initial-sync progress — carry the account state only, no LinkedIn content. This distinguishes Curviate from metadata-only webhook systems: your handler receives everything it needs in one delivery, with no follow-up fetch required. - A
Curviate-Signatureheader — an HMAC-SHA256 digest of the delivery body using your secret. Always verify this before processing.
Delivery is at-least-once. Curviate retries failed deliveries (non-2xx or
timeout) up to five times with exponential backoff. Use the id field in every
payload as a natural deduplication key on your side to handle rare duplicate
deliveries safely.
Account IDs
The account_ids field is required and must be a non-empty array of acc_…
IDs — each a connected LinkedIn account owned by your tenant. Deliveries are scoped
to the accounts you list. To receive events from all your connected accounts, provide
the full set:
{
"account_ids": ["acc_YOUR_ACCOUNT_ID", "acc_YOUR_SECOND_ACCOUNT_ID"]
}You can update the list at any time via PATCH /v1/webhooks/{id} without rotating
the signing secret.
Retrieving a webhook
Fetch a single webhook by id with GET /v1/webhooks/{id}. The response is the same
webhook object — the plaintext secret is never returned on a read, only its
8-character secret_prefix.
curl "https://api.curviate.com/v1/webhooks/wh_01JR8M5KXYZ0000000001" \
-H "Authorization: Bearer cvt_live_YOUR_API_KEY"Deleting a webhook
curl -X DELETE "https://api.curviate.com/v1/webhooks/wh_01JR8M5KXYZ0000000001" \
-H "Authorization: Bearer cvt_live_YOUR_API_KEY"{
"object": "webhook_deleted",
"id": "wh_01JR8M5KXYZ0000000001"
}Deleting an already-deleted webhook returns 200.
Next steps
- Event reference — all event types with payload examples and LinkedIn-specific timing notes.
- Verifying signatures — parse the
Curviate-Signatureheader and validate HMAC in TypeScript or Python. - Delivery & retries — retry schedule, health status, and duplicate-delivery handling.