project.resource.updated

A resource's title, description or on/off switch changes, or a recovery moves it onto another place.

Ability to subscribeproject-resource:view

When this fires

A creator changes one of the three editable fields on a resource (title, description or active) and at least one of them is actually different afterwards. Every surface that can make that change raises it:

  • Dashboard: the resource editor on the project's Resources page, and the on/off switch on each resource row.
  • REST: PATCH /v1/projects/{project}/resources/{resource} for title and description edits, and POST /v1/projects/{project}/resources/{resource}/activate / deactivate for the switch.
  • MCP: the update_resource, activate_resource and deactivate_resource tools.

It also fires when the place behind a resource is swapped: a Disaster Recovery replacement, an automatic failover to a standby, Swap & Grant Resource from the resources list, or the undo of any of those. That event carries changes.space_id with the previous and the new space, changes.kind when the platform upgraded the place in the same move (a group that became a supergroup), and resource.space already reads the new place.

It does not fire when:

  • Nothing changed. A PATCH that re-sends the stored values, or an activate call on a resource that is already active, writes nothing and emits nothing.
  • The place is linked for the first time or removed. That is the connector's link (project.resource.linked) or an unlink (project.resource.unlinked).
  • The resource is deleted. That is project.resource.deleted, and no updated event precedes it.

There are no project.resource.activated / deactivated events. Switching a resource on or off arrives here, as changes.active, alongside title and description edits. One save is one event, and it lists only what changed.

Caveats

  • The description is not in the resource snapshot, matching every other project.resource.* event, but when the description is what changed, changes.description.to carries the new text in full. Read it from there rather than following up with a request to the resource endpoint.
  • Switching a resource off does not touch the plans that sell it. The connector stops granting that one place while the plans keep selling everything else, so a changes.active flip to false is "this perk is paused", not "this plan changed". No plan.updated follows.
  • An activate / deactivate call and a PATCH that sets active produce the same event with the same changes.active shape. The payload does not say which route was used.
  • A swap that also switches an inactive resource back on carries changes.active beside changes.space_id, because the swap reactivates what it repairs.
  • changes contains only the fields that mutated. A PATCH carrying all three fields where only one differs reports one key.

Related events

  • project.resource.created: the manual perk this event later edits.
  • project.resource.linked / project.resource.unlinked: the place bound for the first time or removed, which this event never reports.
  • project.resource.deleted: terminal state for a resource.
  • project.resource.status_changed: the health transition that usually precedes a recovery swap.
  • recovery.resource_replaced / recovery.resource_failed_over: the recovery ledger's own word for the same swap.

Header Parameters

SB-Signature*string

t=<unix seconds>,v1=<hex>: the HMAC-SHA256 of "<t>.<raw body>" under the endpoint's secret. Verify it before acting, and refuse a t more than 300 seconds from now. During a secret rotation a v0= signature under the previous secret may precede v1=.

SB-Event-Id*string

The event's ULID, bare. The envelope's id is the same ULID prefixed evt_, so strip the prefix before comparing. Deduplicate on it: a retry carries the same id.

SB-Event-Name*string

The event name, the same as the envelope's type.

Content-Type*string

Always application/json.

User-Agent*string

Always Subscriby-Webhooks/1.0.

Request Body

application/json

The signed JSON envelope posted to your endpoint.

TypeScript Definitions

Use the request body type in TypeScript.

The envelope every event is delivered in.

Response Body

Example Requests

POST/project.resource.updated

How is this guide?