Documentation / Workflows

Triggers and events

Minimum role
Organisation admin
Applies per
organisation
Last updated
11 October 2026
aishaa version
80c056408

Menu path: Account > Workflows > (open a workflow) > When

In short: every workflow starts on exactly one kind of event (the trigger), optionally narrowed down with conditions. This article is the reference: per event the technical name, the label in the editor, when it fires, all fields it passes along (with type and choice values) and the content fields a step can read. After that comes exactly how trigger conditions compare.

Where to find this

Account > Workflows, open a workflow. At the top is the When block with the This happens dropdown (the event), Only if (the conditions) and Never twice at once for (the concurrency key).

Who: from the role Organisation admin, for the workflows of an organisation whose AI settings you manage. Only an Account admin can create or change a workflow for the whole account.

The When block of an opened workflow under Account > Workflows, with the This happens dropdown, the Only if block with a condition (Field, operator, Compare with) and the Never twice at once for field.

How a trigger works

  • A workflow has one trigger: {"event": "<event>", "conditions": [...]}. In the editor you choose the event under This happens.
  • For every event of that kind, aishaa checks the conditions. If they are all met (or there are none), a run starts on the live version of the workflow.
  • Every workflow whose trigger matches starts. There is no order or priority between workflows and no workflow passes the work on to another.
  • At most one run starts per workflow and event.
  • A workflow never reacts to an event it caused itself.
  • An event that is 5 or more links deep in a chain of automations no longer starts any work. The run is then recorded as stopped, to prevent a loop.
  • A workflow of one organisation only reacts to events of that organisation. A workflow of the whole account reacts to events of all organisations of the account.
  • An event only contains references (ids) to tickets, messages, customers and records, never their content. You read the content in a step through the content fields (see below).

Overview of all events

Technical name Label in the editor When
message.received A message comes in A customer or someone outside the organisation sends a live message in a conversation.
message.understood Message read aishaa has read and understood a customer message. The moment to sort and answer it.
action.resolved An action is handled A proposal, request or task leaves the “waiting” status: carried out, failed, rejected, answered or expired.
object.linked Something is linked to a customer A record (an order, a dossier) or something aishaa keeps itself now belongs to a customer.
object.unlinked A link to a customer is removed Something no longer belongs to a customer.
recording.transcribed A conversation is transcribed A recorded conversation with a customer has been transcribed.
ticket.created A conversation starts A customer opens a new conversation with a first message, or a colleague starts one.
ticket.status_changed A conversation’s status changes The status of a conversation changes, by a colleague, a rule or aishaa.
ticket.assigned A conversation is assigned A conversation gets a (different) colleague, or nobody any more.
schedule.due On a schedule The workflow’s own schedule comes round, for example every Monday at 9:00.

Events a customer is waiting for (message.received and message.understood) run with priority. All others run in the background.

Field types

Every field has a type. It determines how a condition compares it and how you use it.

Type Meaning
id A number or code that points to something (a ticket, a colleague, a customer).
string Text. If there is a list of choice values, it is always one of those values (technical name, written case-sensitively, but a condition compares case-insensitively).
number A number.
boolean true or false.
moment A date and time (ISO 8601).

Fields marked content are not part of the event itself. aishaa reads them at the moment a step uses them (see “Content fields”).

message.received: A message comes in

Fires when a message from outside the organisation comes in live in a conversation: from the customer or from an external participant. Not for imported history and not for messages the organisation sends itself. At this moment aishaa has not read the message yet. If you want to steer on the meaning of the message (topic, urgency, whether a reply is needed), choose message.understood.

Field Label Type Choice values
trigger.ticketId Ticket id
trigger.messageId Message id
trigger.channel Channel string Unknown, Email, WhatsApp, WebWidget, Instagram, TwitterX, Sms, PhoneCall
trigger.senderType Sender string Agent, Customer, AutoReply, ExternalParticipant
trigger.agentUserId Registered by colleague id The colleague who registered the message on behalf of the customer, if so.
trigger.automatedIntelligenceSuppressed Without automatic AI boolean true if no automatic AI was requested for this message when it came in.

Content fields: trigger.ticket.* and trigger.message.* (see “Content fields”).

message.understood: Message read

Fires after aishaa has read and understood an incoming customer message: the question, the topic, the urgency and whether a reply is needed. This is the event on which you sort and answer customer messages. The blocks agent.reply (Write the reply) and case.process (Update cases) only work in a workflow with this trigger.

Field Label Type Choice values and explanation
trigger.ticketId Ticket id
trigger.messageId Message id The message that was read.
trigger.aiRequestId Analysis id The analysis of the message. An agent.reply step completes it.
trigger.channel Channel string Unknown, Email, WhatsApp, WebWidget, Instagram, TwitterX, Sms, PhoneCall
trigger.senderType Sender string Agent, Customer, AutoReply, ExternalParticipant
trigger.replyNeed Reply needed string Required, NotRequired, Unclear
trigger.replyNeedReason Why no reply string Only filled with NotRequired: closing_remark, delivery, notification, handled_elsewhere or unwanted.
trigger.replyNeedConfidence How sure (reply needed) number 0 up to and including 100.
trigger.language Language string The language to reply in, such as nl-NL.
trigger.question Question string The customer’s question in one sentence.
trigger.urgent Urgent boolean aishaa found the message urgent (a deadline, a safety risk, a customer who cannot continue).
trigger.urgencyReason Why urgent string In one sentence; empty if it is not urgent.
trigger.topic Topic string The support area of the main question on the organisation’s topic map; empty if it has not been placed.
trigger.topicDetail Kind of question string The kind of question within that topic; empty if it has not been placed.
trigger.topicId Topic id id The id of that topic. Use this to route on something that does not change when a name changes.
trigger.topicDetailId Kind of question id id The id of that kind of question.
trigger.topicConfidence How sure of the topic (0-100) number How sure the placement is.
trigger.isNewConversation New conversation boolean The message opened the conversation (the first message).
trigger.withinOpeningHours Within opening hours boolean The message came in within the organisation’s opening hours.

Content fields: trigger.ticket.* and trigger.message.*. The text of the message is trigger.message.text.

Good to know about message.understood:

  • The event fires for a message that came in by itself. If a colleague asks for a proposal themselves, no new workflow run starts.
  • If the customer writes again before the previous message has been answered, the open answering runs of the older message stop and the new message takes over.
  • If reading the message fails, the event does not fire.

action.resolved: An action is handled

Fires when an action is no longer waiting: a proposal has been carried out, has failed or has been rejected, a request to a person has been answered, a task has been done, or something has expired.

Field Label Type Choice values and explanation
trigger.actionId Action id
trigger.kind Kind string Plugin, ExternalMessage, ScheduledWake, TicketChange, Request, Task, CustomerMessage, WhatsAppTemplate
trigger.pluginId Plugin string The plugin of the action.
trigger.operationId Plugin action string The action within the plugin.
trigger.status Status string Pending, Executed, Failed, Rejected, Expired, Superseded
trigger.outcome Answer string The answer a person chose for a request; otherwise empty.
trigger.inputEdited Edited by a person boolean A person edited the parameters before it was carried out.
trigger.resolvedByUserId Handled by id Who carried it out, rejected it or answered; empty with automatic handling.
trigger.ticketId Ticket id Empty if the action does not belong to a ticket.
trigger.workflowRunId Workflow run id The run that was waiting for this action, if there was one.
trigger.workflowStepSequence Workflow step number The step number in that run.

Content fields: trigger.ticket.*.

A workflow that is itself waiting for a request, proposal or message does not need this event: the waiting step continues by itself as soon as the action has been handled.

object.linked: Something is linked to a customer

Fires once per new link: a lookup in a connected system found a record for the customer, or a person, aishaa or a workflow linked something. Not when a source confirms an existing link again.

Field Label Type Choice values and explanation
trigger.objectType Object type string record for a record from a connected system, otherwise the kind of something aishaa keeps itself.
trigger.objectKey Object string The id of the object.
trigger.partyId Customer id Empty if the link belongs to the ticket (a conversation without a customer).
trigger.ticketId Ticket id
trigger.source Source string Lookup (found by the lookup), Person (by a person), Ai (by aishaa, a person can undo it), Workflow (by a workflow step)
trigger.strongEvidence Found on e-mail address or phone number boolean Found on the customer’s e-mail address or phone number, or linked by a person.
trigger.linkedByUserId Linked by id
trigger.recordKind Record type string For a record: the kind as the plugin calls it (for example order, dossier).
trigger.pluginId Plugin string For a record: the plugin it comes from.

Content fields: trigger.record.* (only filled if the object is a record), trigger.customer.* and trigger.ticket.*.

object.unlinked: A link to a customer is removed

Fires when the link of an object with a customer ends: a person undid it, or whatever made it has been withdrawn.

Field Label Type Choice values and explanation
trigger.objectType Object type string As with object.linked.
trigger.objectKey Object string
trigger.partyId Customer id
trigger.ticketId Ticket id
trigger.source Source string How the removed link had come about: Lookup, Person, Ai, Workflow
trigger.unlinkedByUserId Removed by id
trigger.recordKind Record type string
trigger.pluginId Plugin string

Content fields: trigger.record.*, trigger.customer.* and trigger.ticket.*.

recording.transcribed: A conversation is transcribed

Fires when a recorded conversation with a customer has been transcribed, with the speakers told apart. What happens next (a report, a task, the dossier) you build in the workflow. You read the text directly as trigger.recording.transcript.

Field Label Type Explanation
trigger.recordingId Recording id
trigger.partyId Customer id Empty as long as nobody has linked the recording to a customer.
trigger.durationSeconds Duration (seconds) number
trigger.language Language string
trigger.speakers Number of speakers number How many people the transcript tells apart.
trigger.recordedByUserId Recorded by id Useful as the assignee of a request or task: {{trigger.recordedByUserId}}.

Content fields: trigger.recording.* and trigger.customer.*.

ticket.created: A conversation starts

Fires when a conversation starts: a customer’s first live message opened it, or a colleague started it. Not for imported history or restored conversations.

Field Label Type Explanation
trigger.ticketId Ticket id
trigger.partyId Customer id
trigger.channel Channel string Unknown, Email, WhatsApp, WebWidget, Instagram, TwitterX, Sms, PhoneCall
trigger.createdByUserId Started by (colleague) id Empty if the customer opened the conversation.
trigger.firstConversation The customer’s first conversation boolean The customer had no earlier conversation yet. Useful for welcoming a new customer.

Content fields: trigger.ticket.* and trigger.customer.*.

ticket.status_changed: A conversation’s status changes

Fires when the status of a conversation changes (closed, reopened, answered, set aside), by a colleague, a rule or an aishaa task. Not for imported history.

Field Label Type Choice values and explanation
trigger.ticketId Ticket id
trigger.partyId Customer id
trigger.status Status string The new status: Open, Answered, Closed, Concept, Pending, Error, Cancelled, Snoozed, WaitingExternal
trigger.previousStatus Previous status string The old status, same values.
trigger.changedByUserId Changed by (colleague) id Empty if a rule or task changed the status.

Content fields: trigger.ticket.* and trigger.customer.*.

ticket.assigned: A conversation is assigned

Fires when a conversation is assigned to a colleague, to a different colleague, or to nobody.

Field Label Type Explanation
trigger.ticketId Ticket id
trigger.partyId Customer id
trigger.assigneeUserId Assigned to (colleague) id Empty (missing) if the conversation is assigned to nobody.
trigger.previousAssigneeUserId Previously assigned to id
trigger.changedByUserId Changed by (colleague) id Empty if a rule or task assigned it.

Content fields: trigger.ticket.* and trigger.customer.*.

schedule.due: On a schedule

Fires when the workflow’s own schedule comes round. This event only starts the workflow the schedule belongs to, never another one. It mentions nothing else: a scheduled workflow looks up what it works with in its own steps.

Field Label Type Explanation
trigger.workflowId Workflow id The workflow whose moment it is.
trigger.scheduledFor Planned moment moment The moment from the schedule. The run may start a minute later.

Content fields: none.

The schedule is in the trigger itself, as trigger.schedule:

Part Values
every hour, day, weekday (Monday to Friday), week or month. Required.
at A time as HH:mm, such as 09:00. Required. With hour, only the minutes count.
days Only with week, required: one or more of monday, tuesday, wednesday, thursday, friday, saturday, sunday.
dayOfMonth Only with month, required: 1 up to and including 28.
timeZone Optional, a time zone such as Europe/Amsterdam. Empty: the organisation’s own time, otherwise the account’s.

A trigger other than schedule.due may not have a schedule. More about setting it up in the editor is in Scheduled workflows.

Content fields

An event only refers to tickets, messages, customers, recordings and records by their id. aishaa offers the content as extra fields under trigger, grouped per object. You refer to them directly in a step, for example {{trigger.message.text}}; no separate step is needed to fetch them.

Object (label) Fields With events
trigger.ticket (Ticket) number (number, Ticket number), title (string, Title), status (string, Status, values as above), channel (string, Channel), urgent (boolean, Urgent), assigneeUserId (id, Assigned colleague), assigneeName (string, Name of the assigned colleague), customerName (string, Customer’s name), customerEmail (string, Customer’s e-mail address), customerPhone (string, Customer’s phone number), createdAt (moment, Created at) message.received, message.understood, action.resolved, object.linked, object.unlinked, ticket.created, ticket.status_changed, ticket.assigned
trigger.message (Message) text (string, Text), senderName (string, Sender), channel (string, Channel), sentAt (moment, Time) message.received, message.understood
trigger.customer (Customer) name (string, Name), email (string, E-mail address), phone (string, Phone number), language (string, Language), createdAt (moment, Created at) object.linked, object.unlinked, recording.transcribed, ticket.created, ticket.status_changed, ticket.assigned
trigger.recording (Conversation) title (string, Title), transcript (string, Transcript), createdAt (moment, Created at) recording.transcribed
trigger.record (Record) title (string, Title), subtitle (string, Subtitle), reference (string, Reference), kind (string, Record type), itemId (string, Number in the system), recordId (id, Record) object.linked, object.unlinked

This is how content fields work:

  • aishaa only reads the content when a step uses the field, and only for that step. A step after a wait step sees the content as it is at that moment.
  • aishaa only reads within the account and the organisation of the run.
  • If the object has disappeared, the fields are empty. You can test that with missing in a step.
  • A customer’s e-mail address and phone number are the primary address and number, otherwise the oldest.
  • trigger.ticket.channel is the channel of the last incoming message, otherwise the channel the conversation started on.
  • A trigger condition cannot read a content field. Test content in a flow.condition (Condition) or flow.switch (Choose a route) step.

Trigger conditions

A condition is {"path": "trigger.<field>", "op": "<operator>", "value": <value>}. In the editor the block is called Only if, with Field, the operator and Compare with.

  • All conditions must be met (and). There is no “or”. If you want to react to one thing or another, use a flow.switch or flow.condition step in the workflow, or create two workflows.
  • Without conditions the workflow reacts to every event of the kind.
  • A trigger condition only reads the event’s own fields (the tables per event above). The path must start with trigger.. A content field such as trigger.message.text or trigger.ticket.customerEmail gives an error: deciding whether a workflow starts must cost nothing. Test content in a step.
  • Conditions cost nothing (no AI is involved). That is why the editor can show, for the latest events, which condition stopped a start.

Operators

Operator Label Met if value
eq is the field is equal to the value required
neq is not the field is not equal to the value (also if the field is missing) required
gt greater than the field is greater than the value required
gte at least the field is greater than or equal to the value required
lt less than the field is less than the value required
lte at most the field is less than or equal to the value required
contains contains the text contains the value; if the field is a list, if an item of the list is equal to the value required
exists is filled the field is there and is not empty (null) none
missing is empty the field is missing or is null none

Write the operator in lower case, exactly as in the table.

How it compares

  • Numbers as numbers. If the field and the value are both a JSON number, aishaa compares them as numbers. So write a number without quotation marks: "value": 80, not "value": "80". With quotation marks it is compared as text, and then "9" is greater than "10".
  • Moments as moments. If both values can be read as a date and time, aishaa compares them as moments.
  • The rest as text, case-insensitive. "whatsapp" is equal to WhatsApp. Yes/no fields compare as the text true or false; "value": true works.
  • A missing field is equal to nothing. eq, gt, gte, lt, lte and contains are then not met; neq is met; missing is met.
  • An empty text ("") counts as filled for exists.
  • contains on text looks for a piece of text, case-insensitive: contains "retour" is also met for "Retourzending".

Examples

Only new WhatsApp conversations outside opening hours:

{
  "event": "message.understood",
  "conditions": [
    { "path": "trigger.channel", "op": "eq", "value": "WhatsApp" },
    { "path": "trigger.isNewConversation", "op": "eq", "value": true },
    { "path": "trigger.withinOpeningHours", "op": "eq", "value": false }
  ]
}

Only conversations that are being closed:

{
  "event": "ticket.status_changed",
  "conditions": [ { "path": "trigger.status", "op": "eq", "value": "Closed" } ]
}

Only recordings that are already linked to a customer:

{
  "event": "recording.transcribed",
  "conditions": [ { "path": "trigger.partyId", "op": "exists" } ]
}

Never twice at once (concurrencyKey)

With concurrencyKey (in the editor Never twice at once for) you give a path in the trigger, usually trigger.ticketId. If a new event comes in with the same value while a run of this workflow is still open (running, waiting or paused), that event starts nothing. If the value is empty, there is no limit. The key too must be one of the event’s own fields, not a content field. More in References, routing, repeating and choosing.

Good to know

  • Every event has one fixed shape. Build conditions on the technical names and values from this article; the labels are what people read in the editor.
  • You can use an id field of a colleague (such as trigger.recordedByUserId or trigger.assigneeUserId) as the assignee of a request or task.
  • For customer messages, almost always choose message.understood: then the workflow already knows what is being asked and an agent.reply step can answer.
  • Under Field, the editor also has the choice Other field… for a path that is not in the list.

Related

Last updated on 11 October 2026. Checked against aishaa version 80c056408. Something wrong or missing? Email support@aishaa.nl.