> This page is for Developer Documentation.

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

# V3 Events

V3 events tell your app that something changed in Benchling, so you can react to it instead of polling. Every V3 event corresponds to a resource in the [V3 REST API](/docs/v3-api-overview): a `v3.run.created` event refers to the same Run resource you can fetch from `/api/v3/run/{run_id}`.

> **Warning**
>
> ### Private beta
>
> V3 events are in private beta and require access to both the V3 REST API beta and V3 events. Contact your account team to request access.
>
> Every V3 event is listed in the public [Webhooks Reference](https://benchling.com/webhooks/reference), but events are only delivered once the necessary flags are enabled on your tenant. Until then, a subscription is accepted and nothing arrives.

If you have not set up webhook delivery before, start with [Getting Started with Webhooks](/docs/getting-started-with-webhooks) and [Receiving Events in Your App](/docs/receiving-events-in-your-app). This page covers what is specific to V3.

## Event types

Event types are named `{developer_platform_version}.{resource}.{action}`:

* **Developer platform version.** The version of the public API the event is emitted from, `v3` here.
* **Resource.** The domain model that changed, in camelCase, matching the V3 API resource.
* **Action.** What happened, such as `created` or `updated`.

V3 currently emits these events:

| Resource      | Created                   | Updated                   |
| ------------- | ------------------------- | ------------------------- |
| Custom entity | `v3.customEntity.created` | `v3.customEntity.updated` |
| DNA sequence  | `v3.dnaSequence.created`  | `v3.dnaSequence.updated`  |
| DNA oligo     | `v3.dnaOligo.created`     | `v3.dnaOligo.updated`     |
| RNA sequence  | `v3.rnaSequence.created`  | `v3.rnaSequence.updated`  |
| RNA oligo     | `v3.rnaOligo.created`     | `v3.rnaOligo.updated`     |
| Project       | `v3.project.created`      | `v3.project.updated`      |
| Entry         | `v3.entry.created`        | —                         |
| Run           | `v3.run.created`          | —                         |

More events are added continuously, with full coverage of all objects expected by late 2026. The [Webhooks Reference](https://benchling.com/webhooks/reference) is the current list; watch the [changelog](/changelog) for additions.

> **Note**
>
> ### There is no field-scoped event type
>
> To act on a change to one particular field, subscribe to the resource's `updated` event and check the `properties` array in the payload, which names the fields that changed. Event types have exactly three segments; a fourth field segment is not a supported subscription target.

V3 events are delivered over webhooks only. EventBridge delivery is not available for them.

## Payload shape

A webhook payload is an envelope with the event in its `message` field. Everything outside `message` is the standard webhook envelope, identical across V2 and V3; `message` is what varies by event type.

**`Example Payload`**

```json title="Example Payload"
{
  "version": "0",
  "baseURL": "https://{tenant_name}.benchling.com",
  "tenantId": "ten_XXXXXXXXXX",
  "app": {
    "id": "app_XXXXXXXXXXXXXXXX"
  },
  "appDefinition": {
    "id": "appdef_XXXXXXXXXX",
    "versionNumber": "0.1.1"
  },
  "channel": "events",
  "message": {
    "type": "v3.dnaSequence.updated",
    "id": "evt_1jdbvuo2740aslk",
    "createdAt": "2026-08-27T22:37:37.975503+00:00",
    "resourceId": "seq_1jdbvuo2740aslk",
    "stability": "beta",
    "deprecated": false,
    "properties": ["name", "folderId"]
  }
}
```

Every V3 event message carries these fields:

| Field        | Description                                                                                   |
| ------------ | --------------------------------------------------------------------------------------------- |
| `type`       | The event type, such as `v3.dnaSequence.updated`.                                             |
| `id`         | The event's own API ID. Use it to deduplicate redelivered events.                             |
| `createdAt`  | RFC 3339 timestamp of when the event was created.                                             |
| `resourceId` | API ID of the resource the event is about. Look it up in the V3 API to get the current state. |
| `stability`  | Stability of the resource type the event is about: `stable`, `beta`, or `alpha`.              |
| `deprecated` | Whether this event type is deprecated.                                                        |

`updated` events add one more:

| Field        | Description                                                           |
| ------------ | --------------------------------------------------------------------- |
| `properties` | Names of the properties that changed, such as `["name", "folderId"]`. |

V3 event payloads are thin: they identify what changed, not the new values. Fetch the resource by `resourceId` from the V3 API to read its current state.

Use the [Webhooks Reference](https://benchling.com/webhooks/reference) or the interactive Webhook Playground (**Feature Settings > Developer Console > Apps > \[App] > Webhook Playground**) to check the exact shape of any event you subscribe to.

## Subscribing to V3 events

Any Benchling App can subscribe to V3 events. The app needs a valid webhook URL to receive them.

Declare the event types in your App Manifest:

```yaml
manifestVersion: 1
info:
  name: Event Test App
  version: 0.0.1
subscriptions:
  deliveryMethod: WEBHOOK
  messages:
    - type: v3.run.created
    - type: v3.entry.created
```

Then upload the manifest through the API (`PUT BenchlingAppDefinitionVersionManifest`) or in the UI when you create or update the app.

### Implicit webhooks

Some webhooks need no subscription and are sent to any app with a valid webhook URL. These cannot be subscribed to:

* `v2.app.installed`

### Activating and deactivating a subscription

A subscription becomes active on a tenant as soon as an app version containing it is installed there. To deactivate one on a particular tenant, do either or both of:

1. Install a version of the app that does not include the subscription.
2. Deactivate the app installation on that tenant.

An app can unsubscribe universally by publishing a new version without the subscription, but active subscriptions on tenants stay active until each tenant installs that new version. If other tenants use your app, keep handling those event types until they have all upgraded.

## Best practices

### Acknowledge webhooks quickly

Your app should acknowledge an incoming webhook with an HTTP 2xx response within 3 seconds.

This matters most for events tied to a subsequent user action in Benchling, such as `v2.canvas.userInteracted`, where a slow acknowledgement shows the user an error saying the app did not respond.

Put incoming webhooks on a queue and process them separately, rather than doing the work before responding. That keeps acknowledgements inside the window no matter how long processing takes.

### Expect out-of-order delivery across resources

Events are ordered per object but not across a tenant. If Project A is updated at time *t* and Project B at *t+1*, delivery is attempted for A before B, but no such guarantee holds between unrelated objects. Do not use arrival order to reconstruct a tenant-wide sequence.

### Permissions

Apps are permissioned the same way as people, and those permissions apply to event subscriptions. An app added to Team A receives events only for objects Team A can access. Apply least privilege when deciding what an app can see.

### Security

Verify every webhook before acting on it. See [Webhook Security](/docs/webhook-verification) for the verification procedure and related guidance.