Applies to VAST Cluster 5.5.
Everything that reaches a DataEngine function is a CloudEvents v1.0 event. Triggers produce them onto a Kafka topic, and functions produce them for the next function in the pipeline. This page lists the attributes each kind of event carries as your handler receives it, and the Runtime SDK property that reads each one.
How events reach your function
- A trigger produces an event onto its Kafka topic: the topic you gave it, or the tenant's default topic.
- DataEngine delivers the event to each function deployment that a link connects to the trigger.
- The runtime turns the event into a
VastEventsubclass chosen by the event'stypeattribute, and calls your handler. - Your handler's return value becomes a new
Functionevent, which DataEngine delivers along each link that starts at your function.
An event whose type isn't one of the four below fails delivery before your handler runs.
Common attributes
Every event has these CloudEvents attributes:
| Attribute | Value | Read it with |
|---|---|---|
specversion |
1.0 |
event.version |
id |
A unique ID for the event. Treat it as an opaque string: on element events it's a string of digits, not a UUID. | event.id |
type |
vastdata.com:<Type>.<Subtype>, or vastdata.com:Function |
event.type (the part before the dot), event.subtype (after it) |
source |
vastdata.com:<trigger name>.<trigger ID> for trigger events; vastdata.com:<deployed service name> for function events |
event.trigger, event.trigger_id; function_trigger on function events |
subject |
<broker>.<topic>. With VAST Event Broker, the broker part depends on the event type: vast-broker-<view name> on element and function events, the bare <view name> on schedule events. |
event.broker (before the first dot), event.topic (after it) |
time |
When the event was produced | event.timestamp |
datacontenttype |
application/json |
event["datacontenttype"] |
data |
The payload | event.get_data() |
Every other attribute is an extension and appears in event.extensions, a dictionary keyed by attribute name. That includes the type-specific attributes below (among them partitionkey on schedule and function events), your trigger's custom extensions and any conditional trigger labels. event.extensions also has a dataschema key, whose value is None.
Element events
An element trigger produces one when an object or file is created or deleted in its source view, or when an S3 object's tags are added or removed. Your handler gets an ElementTriggerVastEvent.
| Attribute | Value | Read it with |
|---|---|---|
type |
vastdata.com:Element.<subtype>, for example vastdata.com:Element.ElementCreated |
event.type is Element; event.subtype is the subtype |
source |
vastdata.com:<trigger name>.<trigger ID> |
event.trigger, event.trigger_id |
subject |
<broker>.<topic>. With VAST Event Broker, the broker part is vast-broker- followed by the broker view's name, so compare event.topic rather than event.broker if you check where an event came from. |
event.broker, event.topic |
elementpath |
<bucket>/<key>: the view's bucket name and the object key (S3) or file path (NFSv4) |
event.bucket, event.object_key |
elementsourcetype |
vast:s3 for S3 objects; vast:nfs for NFSv4 files |
event.extensions["elementsourcetype"] |
knativekafkaoffset, knativekafkapartition |
The topic partition and offset the event was read from, added on delivery | event.extensions |
data |
Details of the change. See below. | event.get_data() |
Element events don't carry a partitionkey attribute. event.partition_key returns elementpath for them.
Subtypes. You choose which changes a trigger reports with S3-style event types (ObjectCreated:*, ObjectRemoved:*, ObjectTagging:Put, ObjectTagging:Delete; see triggers), but the events use other names. A trigger set to ObjectCreated:* delivers events of type vastdata.com:Element.ElementCreated, so event.subtype is ElementCreated. For deletes and tag additions, the 5.5 server's tests show ElementDeleted and ElementTagCreated. Before you branch on event.subtype for anything other than creates, log it from a real event.
data. For an S3 object, data is an S3-style event notification: a dictionary with a Records list holding one record. The record's eventName is the S3 event name, for example ObjectCreated:Put, and its s3 section has the bucket and the object's key, size and ETag. awsRegion holds the VAST cluster's name, not an AWS region. The NFSv4 payload has a different shape. To get the bucket and key, use event.bucket and event.object_key, which come from elementpath and work the same for both.
Element events also carry elementhandle and elementparenthandle. They're internal identifiers; don't rely on them.
Example: an S3 upload
The event delivered to a function when a client uploaded incoming/hello-1.txt to the bucket docs-src, through an element trigger named docs-src-created set to ObjectCreated:*, on the topic default of a VAST Event Broker view named docs-kafka. Captured from the function's logs on VAST Cluster 5.5.0-SP6; IDs and handles are replaced by placeholders.
event.get_attributes():
{
"specversion": "1.0",
"id": "<event-id>",
"type": "vastdata.com:Element.ElementCreated",
"source": "vastdata.com:docs-src-created.<trigger-guid>",
"subject": "vast-broker-docs-kafka.default",
"time": "2026-10-08T12:10:19.407648+00:00",
"datacontenttype": "application/json",
"dataschema": null,
"elementpath": "docs-src/incoming/hello-1.txt",
"elementsourcetype": "vast:s3",
"elementhandle": "<handle>",
"elementparenthandle": "<handle>",
"knativekafkaoffset": "0",
"knativekafkapartition": "5"
}
event.get_data():
{
"Records": [
{
"eventVersion": "2.2",
"eventSource": "vast:s3",
"awsRegion": "<cluster-name>",
"eventTime": "2026-10-08T12:10:19.407648Z",
"eventName": "ObjectCreated:Put",
"userIdentity": {"principalId": "docs-owner"},
"requestParameters": {"sourceIPAddress": "<ip-address>"},
"responseElements": {"x-amz-request-id": "<request-id>", "x-amz-id-2": "<request-id>"},
"s3": {
"s3SchemaVersion": "1.0",
"configurationId": "docs-src-created.<trigger-guid>",
"bucket": {
"name": "docs-src",
"ownerIdentity": {"principalId": "docs-owner"},
"arn": "arn:aws:s3:::docs-src"
},
"object": {
"key": "incoming/hello-1.txt",
"size": 24,
"eTag": "f020733c65f21a3aaee5389d5a5d0da2",
"sequencer": "000500000000000f4241"
}
}
}
]
}
The SDK properties for the same event:
| Property | Value |
|---|---|
event.type, event.subtype |
Element, ElementCreated |
event.trigger, event.trigger_id |
docs-src-created, <trigger-guid> |
event.broker, event.topic |
vast-broker-docs-kafka, default |
event.bucket, event.object_key |
docs-src, incoming/hello-1.txt |
event.partition_key |
docs-src/incoming/hello-1.txt |
The NFSv4 rules (regular files only, NFSv4 only, no events from nested views) are in triggers.
Schedule events
A schedule trigger produces one each time its schedule fires. Your handler gets a ScheduleVastEvent.
| Attribute | Value | Read it with |
|---|---|---|
type |
vastdata.com:Schedule.TimerElapsed |
event.type is Schedule; event.subtype is TimerElapsed |
source |
vastdata.com:<trigger name>.<trigger ID> |
event.trigger, event.trigger_id |
subject |
<broker>.<topic>. With VAST Event Broker, the broker part is the view's name without the vast-broker- prefix that element events carry, so event.broker differs between a schedule event and an element event on the same topic. |
event.broker, event.topic |
cronschedule |
The trigger's schedule, for example 0 * * * * |
event.cron_schedule |
timerelapsedtimestamp |
When the schedule fired, as an ISO 8601 UTC timestamp ending in Z |
event.timer_elapsed_timestamp |
partitionkey |
The event's ID | event.partition_key |
data |
A JSON object with a fixed message string. Don't depend on its content. |
event.get_data() |
timerelapsedtimestamp is the time the schedule fired; time is when the event was produced. Use timerelapsedtimestamp to work out which period a run covers.
If one function serves both schedule and element triggers, compare event.topic, or event.type, rather than event.broker.
Example: a schedule trigger
The event delivered by a schedule trigger named every-2-min (*/2 * * * *) on the topic default of a VAST Event Broker view named docs-kafka. Captured from the function's logs on VAST Cluster 5.5.0-SP6; the trigger GUID is replaced by a placeholder.
event.get_attributes():
{
"specversion": "1.0",
"id": "17914644000033660207",
"type": "vastdata.com:Schedule.TimerElapsed",
"source": "vastdata.com:every-2-min.<trigger-guid>",
"subject": "docs-kafka.default",
"time": "2026-10-08T13:00:00.003000+00:00",
"datacontenttype": "application/json",
"dataschema": null,
"cronschedule": "*/2 * * * *",
"timerelapsedtimestamp": "2026-10-08T13:00:00.003361Z",
"partitionkey": "17914644000033660207",
"knativekafkaoffset": "2",
"knativekafkapartition": "3"
}
event.get_data():
{"message": "Activating trigger by cron"}
| Property | Value |
|---|---|
event.type, event.subtype |
Schedule, TimerElapsed |
event.trigger, event.trigger_id |
every-2-min, <trigger-guid> |
event.broker, event.topic |
docs-kafka, default |
event.cron_schedule |
*/2 * * * * |
event.timer_elapsed_timestamp |
2026-10-08T13:00:00.003361Z |
event.partition_key |
17914644000033660207 |
Function events
A function's return value reaches the next function as a function event. The downstream handler gets a FunctionVastEvent.
| Attribute | Value | Read it with |
|---|---|---|
type |
vastdata.com:Function (no subtype) |
event.type is Function; event.subtype is None |
source |
vastdata.com:<deployed service name>: the name DataEngine gave the upstream function deployment when it deployed it, for example vastdata.com:thumbnailer-nbdn4ypiyaaaa. It's the function deployment's name in the pipeline manifest plus a suffix that DataEngine generates per pipeline, and it's also the upstream function's ctx.function_name. |
event.function_trigger |
subject |
Copied from the event the upstream function received | event.broker, event.topic |
id |
Copied from the event the upstream function received | event.id |
partitionkey |
The partition key of the event the upstream function received. After an element trigger, that's the element's <bucket>/<key>. |
event.partition_key |
time |
When the upstream function returned | event.timestamp |
datacontenttype |
application/json |
|
traceparent |
Present when the incoming event had one, so the downstream spans join the same trace | event.inherited_trace_id |
vastcond<label> |
One attribute per conditional trigger label the upstream function set | event.extensions |
data |
The upstream handler's return value | event.get_data() |
Two consequences:
- The other attributes don't travel. A function event doesn't carry the original event's
elementpath, its custom extensions or other type-specific attributes. If a later function needs the bucket and key, or anything else from the original event, put it in the return value. idstays the same along a chain. If you deduplicate onevent.id, include the function name in the key.
event.trigger, event.trigger_id and event.subtype don't apply to function events: they return None and log these warnings:
vast.dataengine.sdk.event: subtype is not available for function event type
vast.dataengine.sdk.event: Internal function event does not have a trigger, use function_trigger property instead
vast.dataengine.sdk.event: Internal function event does not have a trigger_id, use function_trigger property instead
Example: a chained function
The event received by a function indexer linked after a function thumbnailer, which got the element event for photos/bee.jpg and returned {"bucket": "docs-src", "key": "photos/bee.jpg", "thumbnail_key": "thumbnails/bee.jpg"}. Captured on VAST Cluster 5.5.0-SP6.
event.get_attributes():
{
"specversion": "1.0",
"id": "87982405058564",
"type": "vastdata.com:Function",
"source": "vastdata.com:thumbnailer-nbdn4ypiyaaaa",
"subject": "vast-broker-docs-kafka.default",
"time": "2026-10-08T12:45:01.778000+00:00",
"datacontenttype": "application/json",
"dataschema": null,
"partitionkey": "docs-src/photos/bee.jpg",
"knativekafkaoffset": "0",
"knativekafkapartition": "7"
}
The id is the one the element event for photos/bee.jpg had, and there's no elementpath. event.get_data() returns the upstream return value as a dictionary:
{"bucket": "docs-src", "key": "photos/bee.jpg", "thumbnail_key": "thumbnails/bee.jpg"}
| Property | Value |
|---|---|
event.type, event.subtype |
Function, None |
event.function_trigger |
thumbnailer-nbdn4ypiyaaaa |
event.broker, event.topic |
vast-broker-docs-kafka, default |
event.partition_key |
docs-src/photos/bee.jpg |
Manual events
The SDK also defines a Manual type (vastdata.com:Manual, handled as a ManualVastEvent with no extra properties), for events triggered manually by a user. 5.5 doesn't document a way to send one to a deployed pipeline. Locally, you can send one with vastde functions invoke --event-type vastdata.com:Manual.
Custom extensions
A trigger can add your own key-value pairs to every event it produces: custom_extensions in the trigger file, or --custom-extension key=value on vastde triggers create (see function and trigger files). Each pair arrives as a CloudEvents extension attribute with the key as its name:
# Trigger created with --custom-extension env=prod --custom-extension team=media
env = event.extensions.get("env") # "prod"
Keys contain only lowercase letters and digits, start with a letter, and are 1 to 20 characters long. Choose keys that don't clash with the attribute names on this page.
Conditional trigger labels
When a handler calls event.set_trigger_labels({"tier": "vip"}), each label travels on the resulting function event as an extension attribute named vastcond plus the label name, for example vastcondtier. A link with conditional_trigger_labels delivers the event only if every label on the link matches. See pipeline YAML and the Runtime SDK reference.
Labels are matched on the next hop only. The downstream function sees them in event.extensions, but they aren't carried any further unless that function sets them again.
Test events locally
vastde functions invoke sends an event to a function running locally under vastde functions localrun. --generate-event sends a sample event; --event <file> sends one from a YAML file with the fields id, source, specversion, type, subject, time and data (or data_base64). Any other key becomes an extension attribute.
The sample that --generate-event sends is a smoke test, not a model of a real element event:
- Its type is
vastdata.com:Element.ObjectCreated, soevent.subtypeisObjectCreated, notElementCreated. - It has no
elementpath, soevent.bucketandevent.object_keyareNone, and the SDK logs amalformed vast eventerror. - Its subject,
vastdata.com:kafka-view.default-topic, doesn't have the<broker>.<topic>form, soevent.brokerandevent.topiccome out wrong. event.get_data()returns the whole event (its attributes plus adatakey), not just the payload.
To test code that reads the event, write an event file in the shape of the real element event, and send it with vastde functions invoke --event <file> --url http://localhost:<port>/:
# Illustrative only: an element event for local tests, modelled on a captured 5.5 event.
id: "test-0001"
specversion: "1.0"
type: "vastdata.com:Element.ElementCreated"
source: "vastdata.com:my-trigger.00000000-0000-0000-0000-000000000000"
subject: "vast-broker-media-events.media-uploads"
time: "2026-10-08T10:30:00.123Z"
elementpath: "media/incoming/clip-001.mp4"
elementsourcetype: "vast:s3"
data:
Records:
- eventName: "ObjectCreated:Put"
eventSource: "vast:s3"
s3:
bucket: {name: "media"}
object: {key: "incoming/clip-001.mp4", size: 1048576}
invoke sends the event file the same way as the generated sample, so locally event.get_data() probably returns the whole event rather than only data. Read the bucket and key from event.bucket and event.object_key, which work the same locally and on the cluster, and check any code that reads get_data() against a deployed pipeline. See build and test locally.
See also
- Runtime SDK reference
- Triggers: element and schedule triggers, event types and filters
- Pipeline YAML: links, retries and conditional labels
- KB: Implementing a VAST DataEngine pipeline ("Example CloudEvent Objects") and the class reference