API Docs/Automations/Webhooks
Automations

WebhooksBeta

Get a signed HTTP callback when something happens in your Linkedmash account — a post is saved, archived or labeled, or a draft is created, scheduled, or published.

On timing. Events you trigger in the app (labels, notes, archiving, drafts) fire immediately. bookmark.created is different: saved posts reach Linkedmash through the browser extension, which imports in batches, so a post you save on LinkedIn can arrive up to an hour later and several posts usually arrive in one event. Build your handler to expect a batch rather than one post per call.
Webhooks are a paid feature. Create and manage endpoints from Integrations → Webhooks.

How it works

Register an HTTPS endpoint and pick the events to subscribe to. When a subscribed event fires, Linkedmash POSTs a JSON payload to your URL, signed with your endpoint’s secret so you can verify it’s authentic. Failed deliveries (5xx / network) are retried with exponential backoff.

1

Create an endpoint

Add your HTTPS URL and choose events. Copy the signing secret — it’s shown only once on creation.

2

Receive & verify

Your endpoint receives a POST per event. Verify the X-Webhook-Signature header before trusting the body (see below).

3

Act on the event

Use the event type and data to drive your workflow — sync to a database, notify a channel, or kick off an automation.

Events

Subscribe to any combination of these events per endpoint.

Content Studio

draft.created
A new Content Studio draft was created.
draft.updated
A draft’s content or settings changed.
draft.scheduled
A draft was scheduled to publish to LinkedIn.
draft.published
A scheduled post was published to LinkedIn.

Saved posts

bookmark.created
A LinkedIn post was saved to your library.
bookmark.archived
A saved post was archived.
bookmark.deleted
A saved post was removed from your library.
label.added
A label was added to a saved post.
label.removed
A label was removed from a saved post.

Payload

Every delivery is a POST with this envelope. data is an array of the items affected by the event.

JSON
{
  "id": "2c7bbc6a-34f7-49c9-a8b0-782036c1b989",
  "event": "draft.published",
  "event_ids": ["8f1c2d4e-..."],
  "timestamp": "2026-06-25T10:00:00.000Z",
  "data": [
    { "id": "8f1c2d4e-...", "linkedin_post_id": "urn:li:share:7336731872414035968" }
  ],
  "webhook_id": "a1b2c3d4-..."
}

For saved-post events (bookmark.*, label.*, note.*) each item is hydrated with the post content and its author, so you do not have to call the API back just to read the post. Batches larger than 100 items are delivered as ids only.

JSON
{
  "id": "a22acd3a-14b4-4d02-9033-9fa40b42f56f",
  "event": "bookmark.created",
  "event_ids": ["7483101817589972992"],
  "timestamp": "2026-07-26T20:21:26.836Z",
  "data": [
    {
      "post_id": "7483101817589972992",
      "post_url": "https://www.linkedin.com/feed/update/urn:li:activity:7483101817589972992",
      "text": "The full text of the saved post ...",
      "posted_at": "2026-07-25T08:14:02.000Z",
      "author": {
        "name": "Ethan Mollick",
        "username": "emollick",
        "profile_url": "https://www.linkedin.com/in/emollick",
        "profile_image": "https://media.licdn.com/...",
        "bio": "Associate Professor at The Wharton School"
      }
    }
  ],
  "webhook_id": "a1b2c3d4-..."
}

Headers sent with every delivery:

HTTP
X-Webhook-Signature: sha256=<hex>
X-Webhook-Timestamp: 2026-06-25T10:00:00.000Z
X-Webhook-Event: draft.published
X-Webhook-Id: <delivery id>
User-Agent: Linkedmash-Webhook/1.0

Verifying signatures

Each request is signed with HMAC-SHA256 over the raw request body using your endpoint’s secret. Recompute it and compare in constant time.

Node.js
import crypto from 'crypto';

// req.rawBody must be the exact bytes received (before JSON parsing).
function verify(req, secret) {
  const sig = req.headers['x-webhook-signature']; // "sha256=<hex>"
  const expected =
    'sha256=' + crypto.createHmac('sha256', secret).update(req.rawBody).digest('hex');
  return !!sig && sig.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected));
}
Python
import hmac, hashlib

def verify(raw_body: bytes, header_sig: str, secret: str) -> bool:
    expected = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(header_sig or "", expected)
Verify against the raw body before parsing JSON — re-serializing can change the bytes and break the check.

Delivery & retries

Respond 2xx to acknowledge. On a 5xx or network error we retry up to 4 times with exponential backoff (~1, 2, 4 minutes). A 4xx is treated as permanent and not retried. Recent deliveries (status + response code) are visible on each webhook’s settings.

Best practices

  • Always use HTTPS and verify every signature.
  • Treat the signing secret like a password; rotate by recreating the endpoint.
  • Return fast (≤ a few seconds) and do heavy work asynchronously.
  • Make handlers idempotent — the same X-Webhook-Id may be retried.