Webhooks

Manage your outbound webhook and parse incoming deliveries into typed events. See the Admin overview for how to create the admin client, and the Webhooks API for the underlying event model.

Webhook management lives on the admin client (admin.webhooks); event parsing is a standalone helper exported from the package root.

Register a webhook

A client may hold one active webhook. It receives every event Linked API emits.

typescript
const webhook = await admin.webhooks.set({
  url: 'https://example.com/hooks/linkedapi',
  payloadMode: 'fat', // 'fat' inlines the workflow result; 'thin' sends a reference only
});

console.log(`Webhook ${webhook.id} → ${webhook.url}`);

Params

  • url – HTTPS endpoint that will receive deliveries.
  • payloadMode / payload_mode – optional, "fat" (default) or "thin".

Data

  • id – webhook subscription id.
  • url – the registered destination.
  • payloadMode / payload_mode – current payload mode.
  • isActive / is_active – whether the webhook is active.
  • createdAt / created_at – ISO 8601 timestamp.

There is no update method – to change the destination, delete the webhook and set a new one.

Get the active webhook

typescript
const webhooks = await admin.webhooks.get();
console.log(webhooks[0]?.url ?? 'no active webhook');

Returns an array with at most one entry.

Change payload mode

typescript
await admin.webhooks.setPayloadMode({ id: 'whs-...', payloadMode: 'thin' });

Delete the webhook

Soft delete: the delivery history is preserved and pending deliveries are dropped. You can register a fresh webhook afterwards.

typescript
await admin.webhooks.delete({ id: 'whs-...' });

Inspect deliveries

Return the most recent deliveries (newest first) as a debug feed.

typescript
const deliveries = await admin.webhooks.deliveries();

for (const delivery of deliveries) {
  console.log(`${delivery.eventType} → ${delivery.status} (attempts: ${delivery.attempts})`);
  if (delivery.lastError) {
    console.log(`  last error: ${delivery.lastError} (HTTP ${delivery.responseStatusCode})`);
  }
}

Data

Each delivery has the following shape:

typescript
interface TWebhookDelivery {
  id: string; // delivery identifier, passed to replayDelivery
  eventType: TWebhookEventType; // the event type that was delivered
  eventId: string; // the envelope id of the delivered event
  status: 'pending' | 'delivering' | 'success' | 'failed';
  attempts: number; // delivery attempts made so far
  responseStatusCode: number | null; // HTTP status your endpoint returned on the last attempt
  lastError: string | null; // error text from the last failed attempt
  createdAt: string; // ISO 8601
  updatedAt: string; // ISO 8601
}

Replay a delivery

Re-arm an already-settled delivery. The same event id is reused, so your idempotency handling still applies.

typescript
await admin.webhooks.replayDelivery({ deliveryId: 'whd-...' });

Send a test event

Emit a synthetic webhook.test event to verify a freshly registered endpoint end-to-end.

typescript
await admin.webhooks.sendTest();

Receiving and parsing events

Use parseWebhookEvent / parse_webhook_event to turn a raw request body into a typed, discriminated event. Pass the raw body exactly as received, then branch on type to narrow data.

typescript
import express from 'express';
import { parseWebhookEvent } from '@linkedapi/node';

const app = express();
app.use(express.raw({ type: 'application/json' }));

app.post('/hooks/linkedapi', (req, res) => {
  const event = parseWebhookEvent(req.body as Buffer);

  switch (event.type) {
    case 'workflow.completed':
      console.log(`Workflow ${event.data.workflowId} finished: ${event.data.status}`);
      console.log('Result:', event.data.result); // present in 'fat' mode only
      break;
    case 'account.reconnectionRequired':
      console.log(`Account ${event.data.accountId} needs reconnection.`);
      break;
    case 'webhook.test':
      console.log('Test event:', event.data.message);
      break;
  }

  // Acknowledge fast. A non-2xx response makes Linked API retry with backoff.
  res.sendStatus(200);
});

parseWebhookEvent / parse_webhook_event throws when the body is not valid JSON or is missing the id / type envelope fields. Deduplicate on event.id – deliveries are at-least-once, so the same event can arrive more than once.

The returned union (TWebhookEvent in Node, WebhookEvent in Python) covers workflow events, account events, and the test event. See the Webhooks API for the full event catalog.

Errors

All webhook methods throw LinkedApiError on failure – see Admin overview. For the complete HTTP reference, see the Webhooks API docs.