---
title: Event Triggers and Manual Event Publishing
description: "Event-driven delivery lets Twinnoverse show a layout because something happened. This is different from: - a **data source**, which feeds ongoing dashboard values - a **playlist**, which controls normal playback - a **scheduled campaign**, which runs because a time window matches The normal…"
url: "https://twinnoverse.com/docs/event-triggers-and-manual-event-publishing/"
updated: "2026-06-18"
category: Dashboard Builder / Dashboard Builder delivery
---

# Event Triggers and Manual Event Publishing

Event-driven delivery lets Twinnoverse show a layout because something happened.

This is different from:

- a **data source**, which feeds ongoing dashboard values
- a **playlist**, which controls normal playback
- a **scheduled campaign**, which runs because a time window matches

The normal pattern is:

1. build the regular layout and playlist first
2. make sure the device already plays its baseline content
3. add event triggers only for temporary incident or intervention content

---

## 1. What an Event Trigger Is

An **event trigger** is a rule that connects:

- a stable **event key**
- one saved **layout**
- a **delivery mode**
- a **targeting rule**
- a **duration and priority policy**

When an event is published with a matching event key, Twinnoverse creates device deliveries and the targeted readers show that layout.

The event trigger must already exist and be **active** before manual or API publishing can work.

---

## 2. Event Trigger vs Scheduled Campaign

| Feature | Runs Because | Best For |
| --- | --- | --- |
| **Scheduled Campaign** | A time window or recurrence rule matches | Planned content such as lunch notices, shift reminders, and recurring messages |
| **Event Trigger** | A manual publish or backend event occurs | Machine alarms, quality holds, safety notices, and incident popups |

Use an event trigger when the content should appear only if a real event happens.

---

## 3. Where to Find It

Open **Campaigns** and use these tabs:

- **Scheduled Campaigns**
- **Event Triggers**
- **Publish Event**

The **Event Triggers** tab defines the rules.
The **Publish Event** tab is where an admin can manually publish a one-time event for testing or operations.

![Screenshot 2026 06 18 141951](https://twinnoverse.com/wp-content/uploads/2026/06/Screenshot-2026-06-18-141951-1024x198.webp)

---

## 4. Create an Event Trigger

1. Open **Campaigns -> Event Triggers**.
2. Click **Create Event Trigger**.
3. Enter the trigger name.
4. Enter the **event key**.
5. Select the layout to display.
6. Choose the delivery mode:
   - `fullscreen`
   - `overlay`
7. Set the display duration.
8. Set the priority.
9. Choose the audience mode:
   - `event_prodline`
   - `all_devices`
   - `selected_devices`
10. Set maximum age, queue behavior, and cooldown.
11. Set status to **active** when ready.

The **event key** is the stable identifier that manual publish or an external system will use.

---

## 5. Event Trigger Settings

### Delivery Mode

| Mode | What the User Sees |
| --- | --- |
| **fullscreen** | The event layout temporarily replaces normal playback |
| **overlay** | The event layout appears on top of the current playback |

Use **fullscreen** for critical intervention screens.
Use **overlay** for notices that should not fully interrupt the baseline screen.

### Duration

Duration controls how long the event layout stays visible.

In the current product:

- duration must be greater than `0`
- duration can be up to `3600` seconds
- default event duration is typically `15` seconds

### Priority

Priority helps Twinnoverse decide which event should win when several deliveries compete.

- higher number = higher priority
- readers sort event work by priority first
- if priorities tie, earlier occurrences are considered first

Reserve high priority for truly urgent events.

### Audience Mode

| Audience Mode | Meaning |
| --- | --- |
| `event_prodline` | Route the event to devices whose production line matches the event context |
| `all_devices` | Deliver the event across the organization |
| `selected_devices` | Deliver only to the specific devices chosen in the trigger |

For most factory use cases, `event_prodline` is the safest default.

### Maximum Age

Maximum age controls how old an event is allowed to be before it should no longer display.

In the current implementation:

- maximum age must be greater than `0`
- maximum age can be up to `86400` seconds
- default maximum age is `300` seconds

This helps prevent outdated incidents from appearing too late.

### Queue Behavior

Queue behavior controls what Twinnoverse reader app should do when a new event arrives while a device already has event work pending.

Available values:

- `queue`
- `replace_lower_priority`
- `ignore_new`

High-level meaning:

- `queue` keeps the normal pending queue behavior
- `replace_lower_priority` can replace still-pending lower-priority work
- `ignore_new` skips the new delivery if the device already has pending or claimed event work

### Cooldown

Cooldown helps prevent the same trigger from flooding devices repeatedly in a short time.

In the current implementation:

- cooldown can be `0` or higher
- cooldown can be up to `86400` seconds
- default cooldown is `0`

---

## 6. Manual Publish

Use manual publishing when an operator or admin needs to trigger an event without waiting for an external system.

1. Open **Campaigns -> Publish Event**.
2. Select an **active event trigger**.
3. Select the **production line** if the trigger uses `event_prodline`.
4. The bound layout preview loads.
5. Click widgets in the preview and enter the runtime payload values.
6. Enter the event context fields.
7. Review the preview.
8. Click **Publish Event**.

Important behavior:

- manual publish requires an **active** event trigger
- manual publish reuses the same event pipeline as API publishing
- manual publish publishes one **event occurrence**
- manual publish does **not** save a persistent Manual KPI snapshot

---

## 7. Required Manual Publish Fields

The manual publish flow currently requires:

- `subject_id`

`subject_type` is used in the event context. If you leave it blank in the current manual publish flow, the UI falls back to `operator`.

`subject_name` is optional.

`prodline_id` matters when the trigger uses `event_prodline` audience mode. In that mode, it is operationally required if you want the event to route to the correct production-line devices.

The **Occurred At** timestamp:

- can be left alone and published with the current manual publish value from the UI
- must be handled carefully because an old timestamp can make the event expire sooner based on maximum age

---

## 8. API and Backend Publishing

The same event can also be published from an external system through the event publish endpoint.

Typical use cases:

- PLC alarm connector
- MES exception workflow
- `n8n` automation
- quality incident system
- maintenance escalation bot
- Display operator or prodline achievements

The external publish flow is:

1. create and activate the event trigger in Twinnoverse
2. generate or manage an **event source key**
3. give the integration team the trigger's **event key**
4. have the external system call the publish endpoint when the incident happens
5. include the correct event context and payload for the selected layout

The endpoint uses an **event source token** for authentication.

Supported auth styles:

- `Authorization: Bearer <event-source-token>`
- `x-event-token: <event-source-token>`

---

## 9. Payload Model

Event payloads are **layout-driven**.

That means the payload shape is based on the widgets in the selected layout, not on a separate hardcoded schema per event key.

Practical meaning for end users:

- if the layout changes, the expected event payload changes too
- dynamic widgets need matching payload values
- runtime context widgets stay automatic and do not need manual payload input

This is why manual publish builds its editor from the selected layout.

---

## 10. Example Request Shape

```
{
  "event_id": "evt-20260615-001",
  "event_key": "machine_alert",
  "occurred_at": "2026-06-15T13:27:46Z",
  "context": {
    "prodline_id": "LINE-1",
    "subject_type": "machine",
    "subject_id": "M-204",
    "subject_name": "Filler 204"
  },
  "payload": {
    "kpi": {
      "STATUS": {
        "value": "Stopped",
        "secondaryValue": "Maintenance Required"
      }
    }
  },
  "source_metadata": {
    "source": "factory-backend"
  }
}
```

Notes:

- `occurred_at` is optional in the external publish endpoint
- if `occurred_at` is omitted, backend receive time is used
- `context.prodline_id` is required for meaningful `event_prodline` routing
- the exact `payload` shape depends on the selected layout widgets

---

## 11. What Happens on the TV

When a matching event is accepted:

1. Twinnoverse creates one event occurrence.
2. Twinnoverse creates device-level deliveries for the target audience.
3. Readers poll for pending deliveries.
4. A reader claims a delivery.
5. The reader renders the event layout.
6. The reader acknowledges the result as displayed, failed, or expired.

Reader behavior in the current implementation:

- fullscreen events temporarily replace normal playback
- overlay events appear above the current content
- expired deliveries are discarded
- the local reader queue is bounded, so very old or excess deliveries can be dropped or expired

After the event finishes, normal playback continues.

---

## 12. Best Practices

### Do

- use clear, stable event keys
- keep event layouts short and readable
- use `event_prodline` for line-specific incidents
- reserve high priority for truly urgent cases
- test with manual publish before connecting a backend source
- set maximum age carefully so outdated events do not appear too late

### Avoid

- using event triggers as a replacement for normal KPI playback
- publishing against inactive triggers
- using the same event key for unrelated trigger meanings
- setting a long duration for content that should only flash briefly
- publishing stale timestamps that can make the event expire immediately

---

## 13. Example Use Cases

- machine stopped -> fullscreen alarm layout for the affected production line
- quality hold -> overlay notice on selected devices
- safety incident -> fullscreen notice on all devices
- supervisor broadcast -> manual event publish during a shift handover
