Skip to main content
Events turn a typed message into durable work. An Event definition says which messages it accepts, which target receives them, and which filter must match before RevoEngine schedules anything. One Event definition has one target. Create several active definitions for the same type when one business signal must fan out to independent Jobs or Agents; Event History records which targets matched and which filters skipped delivery.

When to use an Event

Use an Event when work should begin because state changed, not because a person called an Endpoint or a clock reached a particular time.
Publish small event envelopes and let the target load authoritative data by ID. Event metadata is searchable, but it is not a replacement for a Table or Storage object.

Create an Event in the UI

Open Jobs → Events, select Add, and configure the definition. For a Job target, the selected template carries the Component, execution principal, input defaults, limits, concurrency, and retry policy. For an Agent target, delivery uses the current Agent definition.

Configure Runtime input for a Job target

Select a Job target, then use the expanded Options section at the bottom of the Event editor. Runtime input uses the same JSON-object editor as Job templates. The Input mode dropdown shows Override, Deep Override and Replace, with icons and descriptions. Override is shallow: a supplied nested object or array replaces the whole value at that key. Values such as false, 0, and null inside the object are retained. The root must be an object; arrays, strings, numbers, and null are rejected. Use Deep Override to change part of a nested configuration. For example, Job defaults { "export": { "format": "csv", "encoding": "utf8" } } and automation input { "export": { "format": "xlsx" } } produce { "export": { "format": "xlsx", "encoding": "utf8" } }. An empty nested object preserves existing nested values; a change of value type replaces the whole value. Arrays are never concatenated, and null does not delete a field. Existing Override and Replace behavior is unchanged. For example, a Job template with { "region": "eu", "mode": "incremental" } and an Event with { "mode": "full" } in Override mode execute with { "region": "eu", "mode": "full" }. The Platform API uses these fields on the Event definition:
Read the resolved values in the Component:
Event Runtime input configures templateInputs; it does not replace the Event message, type, or user metadata. Agent delivery remains configured through its target settings. The Platform API uses inputMode: "override" for Override, inputMode: "deep_override" for Deep Override and inputMode: "replace" for Replace, matching the UI. Existing definitions are migrated without changing their effective behavior. New definitions default to input: {} and inputMode: "override", preserving Job defaults. On an API update, omitted fields retain their stored values. Send both input: {} and inputMode: "override" to restore the default configuration. Each accepted delivery retains its Runtime input and mode. Editing the Event changes future deliveries; it does not rewrite the input of Jobs already queued or running, or their retry attempts. The Job template continues to own execution policy, concurrency, and retry settings.

Operate configured Events

The Jobs → Events grid is the inventory of current and deleted definitions. It exposes name, category, description, active state, Internal classification, Type, target references, metadata, creation/update ownership, version, and deletion state. Every visible column can be used as an operator filter where its data type allows it. Open a row to review the effective target, delivery mode, metadata, and filter before changing lifecycle state. The header links directly to History, so the definition and its observed deliveries remain separate: Instance settings govern the total and active Event-definition quotas. An active definition whose target was deleted, disabled, or is no longer authorized cannot be admitted until that dependency is corrected.

Create a custom business event

Disable Internal when the signal belongs to your application rather than a RevoEngine resource lifecycle, then enter ORDER_APPROVED in Type. The API stores type: "ORDER_APPROVED", custom: true; no prefix is added. Event names are normalized to uppercase. With Internal enabled, Type is a selector populated from the supported platform catalogue. Switching back to Internal clears a custom name that is not in that catalogue. The usage hint shows api.input('message') for internal messages and api.triggerEvent() for a custom event. Use a stable namespace and past-tense business fact. A custom event should announce something that already happened, not hide a command such as SEND_EMAIL_NOW.

Example: approved high-value order

Create a Job template first, then register one filtered Event definition:
Trigger the definition with a small envelope. The Job should reload the authoritative order and account by ID, verify the balance in a database transaction, create an idempotent transaction record, call the risk provider with a Secret-backed API key, write any durable receipt to Storage, and return its operationId and evidence IDs.
The Event message is routing context, not financial truth. The target must reload balance, order status, and prior transaction state under its own principal before it commits a side effect.

Filter event messages

The visual filter builder supports all, any, and none matching. Enter message paths without the message. prefix; use dot notation for nested properties.
Supported comparisons include equality, numeric ordering, list membership, null checks, contains, starts/ends with, and case-sensitive or case-insensitive pattern matching. The UI accepts only the property inside the event message. For example, enter name, mimeType, or metadata.kind; the editor persists the safe query path as message.name, message.mimeType, or message.metadata.kind. Do not type the message. prefix into the visual field. For a CSV ingestion subscription, configure all conditions:
Wildcard text entered as * is normalized to the query wildcard used by the stored filter. Property paths are limited to safe dot notation; prototype-related segments and prefixed paths are rejected.

Filter operators

The visual builder supports up to six safe message-path segments and deliberately writes only message.* filters. The Platform API accepts a validated filter tree over message.*, searchable metadata.*, or the event type, with nested and, or, and not groups and at most twelve field-path segments. Unsafe keys such as __proto__, prototype, and constructor are rejected on both surfaces.
A filter is an admission rule, not a data validator. Validate the complete business payload in the target Component before creating side effects.

Trigger a controlled test

Saved active custom Events expose Run to AUTOMATION_RUNNER and AUTOMATION_ADMIN.
  1. Open the Event and select Run.
  2. Enter a JSON message representative of production traffic.
  3. Optionally set scheduleFor to an ISO 8601 date-time with timezone or Unix timestamp in milliseconds, from acceptance through 30 days ahead.
  4. Submit and retain the returned eventId and triggerId acceptance receipt.
  5. Open Event History and confirm which targets were scheduled or skipped.
Use scheduleFor when the caller already owns an absolute business deadline:
Use scheduleFor for delayed delivery. A past absolute time or a value more than 30 days ahead is rejected before acceptance.

What exists before a delayed Event is due?

Event History and Jobs for matching Job templates are created immediately, using the filters and targets accepted with the Event. The Event History row exposes its immutable scheduledFor, audit version, and last-update evidence. For an Event scheduled two hours ahead, you can inspect those Jobs now: they wait as SCHEDULED, with the same accepted deadline. The Event message remains the input snapshot; later edits to Event filters do not change this accepted occurrence. When the time arrives, Jobs become eligible for dispatch and still respect concurrency. Delivery retry resumes the accepted work without intentionally creating another Job for the same matched target. Make downstream business effects idempotent as well.
A request timeout is not cancellation. Accepted work can finish materializing through recovery. Check Event History before submitting the same business event again.

Built-in event families

The current catalogue includes lifecycle events for:
  • Storage create, update, synchronize, archive, restore, and delete;
  • legacy File finalize, archive, and delete;
  • User and Service Account create, update, activate, deactivate, restore, and delete;
  • account API-key create, update, and delete.
The custom boolean is the only API classifier. custom: true permits a dynamic business message; custom: false selects a supported platform lifecycle event and can only be replayed from existing history. Matching uses both type and custom, so identical names in different classes do not collide. The UI’s Internal control presents the inverse of custom.

Storage lifecycle cookbook

STORAGE_CREATED is emitted after the Storage record is durable and an upload is finalized. With computeStats: 'async', it can arrive before text statistics; subscribe to STORAGE_SYNCHRONIZED if the first Job must read cached batches immediately. Reports workspace lifecycle messages are not published as customer Storage events. Legacy FILE_FINALIZED, FILE_ARCHIVED, and FILE_DELETED exist only for integrations still using the old Files model. Do not select them for a new Storage workflow.

Incoming file → Event → Job → output

  1. An operator, SDK, or Component uploads a file into the Storage Files workspace and finalization creates a storageEntryId.
  2. STORAGE_CREATED records the entry projection as the Event message. A filter admits only the intended MIME type, folder policy, or user metadata.
  3. The selected Job template starts its Component under the template’s service account. The Job input contains { type, metadata, message }.
  4. The Component reads api.input()?.message.storageEntryId, validates authoritative entry metadata and content, and uses bounded storage.getFileData() batches.
  5. It writes a result with storage.putObject() or a finalized upload session, then returns the operation ID and both Storage entry IDs.
  6. Event History proves admission and target scheduling; Job History, logs, and the output Storage entry prove processing.
Grant the Job service account read access to the input’s complete ancestor ACL chain and write access to the output folder. An Event matching successfully does not bypass Storage authorization at execution time.
See the full file-processing workflow for upload, schema, finalization, and retry-safe output design.

Roles and lifecycle

Updates use a version field for optimistic concurrency. Deleting is recoverable; restoring returns the definition but does not imply that it should immediately be active. Review its target and filter first.

Delivery and failure semantics

Acceptance confirms that RevoEngine recorded the event; it does not mean every target completed successfully. Diagnose fan-out in Event History, then follow the related Job or Agent run for execution-level status. Storage commits are not rolled back if post-commit lifecycle event enqueueing fails. Operators should therefore reconcile important ingestion sources against Storage entries as well as monitor Event History; the durable file remains the source of truth. Event delivery can be repeated by infrastructure or by an operator replay. Targets that call payment, provisioning, or messaging systems must enforce an idempotency key such as eventHistoryId + targetId.

Diagnose by boundary

Confirm the producer used the expected type and the trigger request was accepted. Delayed Job-template targets should already be visible in Event History; inspect their scheduledFor and wait reason. For Storage workflows, also inspect the durable Storage entry because a committed file remains authoritative if post-commit event delivery fails.
Compare the saved normalized message with the definition filter. Check data types as well as values: the number 10000 is not the string "10000" for exact equality.
Continue in Job History or the Agent run. Event History owns admission and fan-out, while target history owns execution, permissions, retries, and result.
Use a more specific business event type or add message/metadata filters. Keep each definition responsible for one target so unwanted fan-out can be disabled independently.

Production checklist

  • Give custom types stable names and set custom: true.
  • Filter before starting expensive work.
  • Validate the payload again inside the target.
  • Use a dedicated service account on Job templates.
  • Correlate Event history with downstream operation IDs.
  • Make every external side effect replay-safe.
  • Disable the definition before changing a production target.
  • Review configured definitions and active quotas periodically; remove obsolete subscribers instead of leaving ambiguous filters active.
See Event History for fan-out evidence and replay, Jobs for durable target execution, and Storage for lifecycle, ACL, retention, and batching semantics.

Available native event types

The Event editor retrieves the currently supported native types from GET /api/v1/automation/event-types. The catalogue covers existing Storage, legacy Files (including FILE_UPDATED), user, Service Account and API-key lifecycle producers. It excludes unavailable autonomous inbox types. Previously saved types remain visible for inspection; a catalogue loading failure disables type selection. Disable Internal and enter Type for application-owned events.

API key expiry events

ACCOUNT_API_KEY_EXPIRING announces an upcoming expiry at a planned reminder instant. ACCOUNT_API_KEY_EXPIRED is emitted when the key’s expiry becomes due. The native lifecycle includes 7-day, 24-hour and expiry instants; authorized human preferences can add first-reminder and custom automation-only offsets. Events at an identical offset for the same key and expiry share one occurrence. Notification email/System-message opt-out does not stop these events. For a reminder one day before expiry, select ACCOUNT_API_KEY_EXPIRING and add this filter in the visual editor:
The Platform API filter uses message.reminderDays. Add message.userId or message.userKeyId to scope the integration. The target should reload current key/account metadata under its execution principal and make its reaction idempotent with noticeId. Do not assume that a replacement has already been installed in the consumer merely because rotation created it. Reminders are published when due, after current key-state validation. Revocation or a changed rotation cutoff suppresses obsolete occurrences; uncertain account changes defer processing. Existing-key adoption schedules future stages only.

Chain Component Jobs from execution outcomes

Use these native types to start a follow-up Job from a committed execution outcome: These types cover ordinary Component Jobs. Cancellation, platform operations and Webhook delivery do not publish these events. Existing terminal Jobs are not replayed when the feature is enabled. For a success chain, select JOB_EXECUTION_SUCCEEDED, choose the follow-up Job template and filter by the source jobTemplateId. In the visual filter editor enter jobTemplateId; the API filter uses message.jobTemplateId. An unfiltered definition accepts outcomes from every matching Job template. The message carries jobId and executionId for the source attempt, executionSeriesId for the execution series, jobTemplateId, name, category, status, completedAt, processingTime, executionUserId, initiatedByUserId, requestedFrom and retry context: retryRootJobId, retryParentJobId, retryAttempt, retryMode, retryScheduled, retryScheduledFor and final. Failed outcomes include a bounded errorCode and may include a processing recovery reason. Inputs, outputs, secret values, error messages and stack traces are excluded. Automatic retries retain executionSeriesId. A manual retry starts a new execution series, while historical retry links and the attempt counter remain available. A final failure describes the automatic retry policy at that point; an operator can still retry manually afterward. The target executes with its configured principal and must load any source data it needs through authorized APIs. Event delivery may be retried. Targets should make their business side effects idempotent. Lifecycle chains retain their Event-definition ancestry: a repeated definition is skipped with JOB_EVENT_CHAIN_CYCLE, and a chain beyond 32 definitions is skipped with JOB_EVENT_CHAIN_DEPTH_EXCEEDED. Event History records these skipped deliveries, including when replaying an outcome. Manual Job execution or manual retry starts fresh ancestry.
Last modified on October 14, 2026