Asset event webhook service reference
This page specifies the payload structure, event fields, event types, filter configuration, delivery behaviour, and authentication options for the asset event webhook service.
Payload structure
Each webhook delivery is a JSON object with the following structure:
{
"count": <integer>,
"events": [<EventObject>, ...],
"webhookTimestamp": "<ISO-8601 UTC timestamp>"
}
count-
Type: integer. The number of event objects included in this payload.
events-
Type: array. The list of individual asset change event objects included in this delivery. See Event object for the structure of each object.
webhookTimestamp-
Type: ISO-8601 UTC timestamp. The time at which this webhook payload was generated.
Event object
Each element in the events array represents a single change to an asset.
{
"atomId": <integer or null>,
"eventId": "<uuid>",
"eventTimestamp": "<ISO-8601 UTC timestamp>",
"assetId": <integer>,
"assetUuid": "<uuid>",
"eventType": "<string>"
}
atomId-
Type: integer or null. Internal reference to the asset’s latest version. Null for
PURGEDevents, where the asset is no longer recoverable. eventId-
Type: UUID. Unique identifier for this event instance. Use this field for deduplication in receiving systems.
assetId-
Type: integer. The asset’s internal ID in the source system. Consistent across all events for the same asset.
assetUuid-
Type: UUID. Persistent unique identifier for the asset. Remains the same across all versions of the asset.
eventType-
Type: string. The type of change that occurred. See Event types for valid values.
eventTimestamp-
Type: ISO-8601 UTC timestamp. The time at which the event occurred in the system.
Event types
| Event type | Description |
|---|---|
|
A new asset has been created. |
|
An existing asset’s metadata or content has been updated.
Multiple edits within a single delivery interval are collapsed into a single |
|
The asset has been moved to the Trash and is no longer active.
The asset can be restored by an administrator at any time.
Treat this event as "archive or hide" in receiving systems — the asset may return via a future |
|
The asset has been permanently removed and cannot be recovered.
|
|
A new binary or version of the asset has been uploaded or promoted. |
Filter kinds
Filter kinds define which asset fields a filter evaluates against.
| filterKind | Payload field | Description | Example values |
|---|---|---|---|
|
|
Tags or keywords attached to the asset. |
|
|
|
Custom metadata fields.
Accepts an optional |
Field: |
|
|
Workflow state of the asset. |
|
|
|
Schema identifier. |
|
|
|
Asset type identifier. |
|
|
|
Domain or tenant identifier. |
|
|
|
Parent asset ID.
Use |
|
Filter conditions
The condition field controls how values within a single filter group are matched.
| Condition | Logic | Use case |
|---|---|---|
|
All specified values must be present. |
Asset must have all specified keywords. |
|
At least one specified value must be present. |
Asset must have any one of the specified keywords. |
|
None of the specified values must be present. |
Exclude assets with specific keywords. |
The logic between separate filter groups is always AND. All configured filter groups must pass for an event to be delivered.
Filter evaluation rules
Processing order
The service evaluates each event against the following checks in order. An event must pass all applicable checks to be included in delivery.
-
Purged events bypass all filters: Events with type
PURGEDalways pass through to delivery, regardless of any filter configuration. This ensures hard deletes are never silently dropped. -
Resource type check: The event’s supertype must match the configured
resourceTypes. If noresourceTypesare configured, only"Resource"supertypes pass by default. -
Event type check: If
eventTypesare configured, the event must match one of them. If noeventTypesare configured, all event types pass. -
ParentId default check: Unless a
parentIdfilter is explicitly configured, only top-level assets (those withparentId: null) pass. Child assets are excluded by default. -
Custom filters: Any configured
filtersare evaluated. All filter groups must pass; the logic between separate filter groups is always AND.
Default behaviours
If a configuration option is omitted, the following defaults apply.
| Configuration | Default behaviour |
|---|---|
No |
Only |
No |
All event types are delivered. |
No |
No additional filtering is applied. |
No |
Only top-level assets ( |
Delivery behaviour
HTTP method-
Webhook requests are sent as HTTP POST requests with a
Content-Typeofapplication/json. Delivery interval-
The service executes approximately every minute. All asset change events that occurred within the interval are collected and delivered as a single payload.
Batch size-
Each payload contains a maximum of 100 events by default. This limit is configurable — contact App Support if you require a smaller batch size. Payloads are capped at 16 MB regardless of batch size configuration. Where asset activity exceeds these limits within a single interval, multiple payloads are delivered.
EDITED event grouping-
Multiple edits to the same asset within a single delivery interval are collapsed into a single
EDITEDevent. The payload reflects the asset’s state at the point of delivery. Retry behaviour-
If the receiving endpoint returns a non-2xx response, the service retries delivery up to five times using exponential backoff, starting at one minute and increasing to a maximum of eight minutes between attempts. Client errors (4xx) are not retried. Events that cannot be delivered within 24 hours are moved to an internal dead-letter store for operator review.
Replay-
There is no manual replay mechanism for failed events. If you suspect missed events, contact App Support with the approximate time window and any expected event IDs.
Delivery monitoring-
There is no built-in monitoring or alerting for webhook delivery failures. Receiving systems should implement their own observability on the endpoint.
Authentication and headers
API key-
The service supports API key authentication via the
x-api-keyrequest header. OAuth is not supported. Theapikeyconfiguration value is the name of a GCP Secret Manager entry, not the secret itself. App Support creates the Secret Manager entry and configures the field on your behalf. The service resolves the secret at runtime and sends it in theX-API-Keyheader with each request. Key rotation is a manual process handled through App Support. Custom headers-
Additional custom headers can be added to webhook requests. Contact App Support to specify custom headers at configuration time.
Configuration examples
No authentication (default)
Use when the endpoint accepts requests without checking credentials. Typical for development, QA, and public webhook test services.
assetUpdater:
webhooks:
- url: "https://example.com/webhook/asset-events"
enabled: true
resourceTypes:
- "Resource"
API key authentication
Use when the endpoint requires an X-API-Key header.
The apikey value is the name of a GCP Secret Manager entry, not the secret value itself.
App Support creates the Secret Manager entry and fills in this field on your behalf.
assetUpdater:
webhooks:
- url: "https://api.acme.com/storyteq/asset-events"
enabled: true
apikey: "acme-prod-webhook-key" # Secret Manager entry name
resourceTypes:
- "Resource"
eventTypes:
- "Created"
- "Edited"
The service resolves the secret at runtime.
The resulting request includes the resolved secret value in the X-API-Key header:
POST /storyteq/asset-events HTTP/1.1 Host: api.acme.com Content-Type: application/json X-API-Key: <resolved-secret-value>
Full configuration reference
The following shows all available configuration options.
All options marked # OPTIONAL can be omitted; see Filter evaluation rules for default behaviours when omitted.
assetUpdater:
webhooks:
- url: "https://your-webhook-endpoint.com/events"
enabled: true
apikey: "your-secret-manager-entry-name" # OPTIONAL: Secret Manager entry name
headers:
X-Custom-Header: "value" # OPTIONAL: Additional request headers
resourceTypes: # OPTIONAL: Resource type filtering
- "Resource"
- "Project"
eventTypes: # OPTIONAL: Event type filtering
- "Created"
- "Edited"
- "Deleted"
- "Purged"
- "Reversion"
filters: # OPTIONAL: Custom filters (all must pass)
- filterKind: keywords
condition: ANY
value:
- "VALUE1"
- "VALUE2"
- filterKind: additionalFields
condition: ANY
fieldName: "field_name"
value:
- "expected_value"
- filterKind: state
condition: ANY
value:
- "State Name"
- filterKind: typeId
condition: ANY
value:
- "66"