> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.vlenseg.com/llms.txt.
> For full documentation content, see https://docs.vlenseg.com/llms-full.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.vlenseg.com/_mcp/server.

# Webhooks

Webhooks let your server react to events on the Vlens platform in real time, without polling. When an event occurs, Vlens sends an `HTTP POST` with a JSON payload to a URL you configure in the Vlens portal.

***

## Use cases

Webhooks support:

* Tracking contract lifecycle changes (creation, approval, signing, countersignature)
* Synchronizing contract status with external systems
* Triggering automated workflows on contract events
* Maintaining audit and monitoring dashboards

***

## Available events

| Event                             | Triggered when                    |
| --------------------------------- | --------------------------------- |
| `App.BusinessRequestStatusChange` | A business request changes status |

***

## Setting up a subscription

1. Sign in to the Vlens portal
2. Navigate to **Webhook Subscriptions**
3. Click **Add New Webhook Subscription**
4. Provide:
   * **Webhook Endpoint** — the URL that will receive `POST` notifications
   * **Webhook Events** — one or more events to subscribe to
5. Click **Save**

Subscriptions are **event-specific** and **endpoint-specific** — multiple subscriptions can target the same event with different endpoints (useful for fan-out to different downstream systems).

***

## Payload format

Every webhook delivery is a `POST` with a JSON body:

```json
{
  "Id": "2b020a26-ec12-4f59-8e6a-7d4bf941372b",
  "WebhookEvent": "App.BusinessRequestStatusChange",
  "Attempt": 1,
  "Data": {
    "Id": "c2f27bd2-bb49-4dde-bb5f-22a6b8e0d20d",
    "NewStatus": "PendingApproval"
  },
  "CreationTimeUtc": "2025-12-11T11:27:18.6197007Z"
}
```

| Field             | Description                        |
| ----------------- | ---------------------------------- |
| `Id`              | Unique delivery ID                 |
| `WebhookEvent`    | The event name                     |
| `Attempt`         | Delivery attempt number            |
| `Data`            | Event-specific payload (see below) |
| `CreationTimeUtc` | When the event occurred (UTC)      |

### `Data` for `BusinessRequestStatusChange`

| Field       | Description                                                                                         |
| ----------- | --------------------------------------------------------------------------------------------------- |
| `Id`        | The business request UUID                                                                           |
| `NewStatus` | The new status name — e.g. `PendingApproval`, `Approved`, `CustomerSigned`, `ServiceProviderSigned` |

***

## Receiving a webhook

```javascript
import express from "express";

const app = express();
app.use(express.json());

app.post("/webhooks/vlens", (req, res) => {
  const { Id, WebhookEvent, Data, Attempt } = req.body;

  // Acknowledge receipt quickly — process async
  res.status(200).send("ok");

  // Deduplicate using Id
  if (alreadyProcessed(Id)) return;
  markProcessed(Id);

  if (WebhookEvent === "App.BusinessRequestStatusChange") {
    handleContractStatusChange(Data.Id, Data.NewStatus);
  }
});

app.listen(3000);
```

***

## Delivery logs

Every webhook delivery is logged and viewable in the Vlens portal. Each log entry includes:

* HTTP method (`POST`)
* Source IP address
* Timestamp
* Request headers
* Request body

Use the delivery log to debug failed or unexpected deliveries.

***

## Common patterns

### Reconcile on completion

```javascript
if (WebhookEvent === "App.BusinessRequestStatusChange"
    && Data.NewStatus === "ServiceProviderSigned") {
  // Contract fully executed — sync to internal systems and notify the customer
  await crm.markContractCompleted(Data.Id);
  await sendCustomerNotification(Data.Id);
}
```

### Polling fallback

For mission-critical workflows, combine webhooks with periodic polling of
`GET /api/BusinessRequest/CurrentListIds` to catch any missed deliveries.