Documentation / Workflows

Data from connected systems in a workflow

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

Menu path: Account > Workflows > (open a workflow) > Add step

In short: a workflow can read data from the systems the organisation has connected through plugins and do something in them. You read with plugin.read (with parameters you fill in yourself, often in a chain) or with record.find and record.read (the customer’s record and its details). You do something with plugin.action, by default as a proposal a colleague approves. You calculate and format with data.format, never with the AI. Which actions and reads exist differs per organisation.

Where to find this

Account > Workflows, open a workflow, Add step. The read blocks are in the group Fetch, plugin.action and document.create in Do, data.format in Work on. Who: from the role Organisation admin. Connecting and switching on a plugin is done separately, see Set up an integration.

A Fetch from a connected system step in the workflow editor with the What to read dropdown (the read operations of the connected systems) and the Parameters field with an inserted value from an earlier step.

Which way to choose

You want Use
The customer’s name, e-mail address or language, the text of the message, the transcript of a recording No step: a content field such as {{trigger.customer.email}} or {{trigger.message.text}}.
The customer’s record of one kind (their dossier, their order) record.find
The details of that record (order lines, status of the dossier) record.read, with the recordId from record.find
Look something up with a value you have (a serial number, an order number from the message) plugin.read with that value as a parameter
Look something up with what an earlier lookup returned A chain of plugin.read steps
Do something in the system (change an order, upload a document, make an appointment) plugin.action, by default as a proposal
Send a PDF along to the system document.create, then plugin.action with the attachmentId
Work on a date, amount or list for a parameter or a message data.format
Pull a value out of free text (a serial number in the message) ai.transform with a schema

Which actions and reads an organisation has

What you can choose depends on the plugins that are connected and switched on in the organisation, and on their wiring. For each plugin, aishaa uses the first switched-on connection.

What For block Which ones exist
Plugin actions plugin.action (action) The actions of the connected plugins, except actions that are switched off for the organisation.
Plugin reads plugin.read (read) Read operations the plugin offers to the AI, with exactly one input, with described parameters, that do not return a file.
Record reads record.read (read) Read operations that the plugin’s wiring binds to a record through the record’s id alone, without a file. Each operation lists the record kinds it reads.
Record kinds record.find (kind), message.check (kind) The record groups the connected systems offer, the same as the record tabs on the ticket.

In the editor, the dropdowns only offer what exists. An AI assistant sees the same in the “This organisation” part of the guide that workflows_get_guide returns: for each plugin action and each plugin read the pluginId/operationId, the title, the description and the parameter schema; for each record read the record kinds; and the record kinds with their name and plugins. If it says “cannot be used here”, the organisation cannot use that block. The organisation can partly decide for itself what a plugin offers; see Decide for yourself what a plugin offers.

Reading with plugin.read

plugin.read calls one read operation with the parameters in input. The answer is in {{<step>.data}}.

  • The parameters must fit the operation’s schema. If they do not, the step goes via failed with an error that says what is wrong.
  • If the system does not know what was requested, the step goes via none. Always connect none and failed to something useful: a question to a colleague, or an agent that answers without that data.
  • plugin.read only reads. What the answer says about a customer or record is not recorded as an identity.

A chain of reads

A chain is a series of plugin.read steps in which each step uses a value from the answer of the previous one. Such a chain often ends in a plugin.action.

[
  { "id": "machine", "label": "Find the machine by serial number", "block": "plugin.read",
    "inputs": { "read": "service/machine_by_serial", "input": { "serialNumber": "{{serienummer.serial}}" } },
    "exits": { "found": "storing", "none": "vraag-collega", "failed": "vraag-collega" } },
  { "id": "storing", "label": "Fetch the fault history", "block": "plugin.read",
    "inputs": { "read": "service/faults_by_asset", "input": { "assetReference": "{{machine.data.assetReference}}" } },
    "exits": { "found": "werkorder", "none": "werkorder", "failed": "vraag-collega" } }
]

This is a fragment: before it is a step serienummer (an ai.transform that pulls the serial number out of {{trigger.message.text}}), and the steps werkorder (a plugin.action) and vraag-collega (a human.request) follow. The names service/machine_by_serial and service/faults_by_asset are examples. Always use the pluginId/operationId from the organisation’s list, and the field names from the schema and the answer of that operation.

The customer’s record: record.find and record.read

record.find searches among the records linked to the run’s customer on strong evidence (found on e-mail address or phone number, or linked by a person). A record that was only found by name does not count: it may belong to someone with the same name.

  • found: exactly one record. Use {{<step>.recordId}} for record.read and {{<step>.itemId}} (the number in the system) or {{<step>.reference}} for the parameters of a plugin action.
  • several: more than one. The separate fields contain the newest; {{<step>.records}} is the list (at most 10), which you can go through with flow.foreach or put to a colleague.
  • none: no record, or the run has no customer.

record.read then reads the details of that record. The record itself determines what the operation is called with; you only pass read and record. The read operation must come from the same plugin as the record and read records of that kind.

Doing something: plugin.action

plugin.action creates an action in the connected system, through the same process as an action a colleague or an agent proposes.

  • As a proposal ("mode": "propose", the default): the action appears in To do and on the ticket if the run has one. A colleague approves, edits the parameters or rejects. The step waits and continues via executed, failed, rejected or expired (after the deadline, 7 days by default).
  • At once ("mode": "execute"): the action happens straight away, in the name of the workflow. Only use this if the organisation trusts the workflow.
  • You read what was actually carried out in the output: {{<step>.input}} (the parameters as carried out), {{<step>.edited}} (whether a colleague edited them), {{<step>.result}} (the plugin’s answer).
  • Pass a summary: one sentence the colleague reads. And an assignee if a particular colleague has to decide.
  • If a step on proposal has been approved unchanged 10 times in a row, aishaa offers Do this itself from now on (see Building blocks of a workflow).

Sending a document along: document.create

document.create makes a PDF from a text and keeps it with the customer. You pass the output {{<step>.attachmentId}} in the parameter of the plugin action that accepts an attachment. A plugin action in the same run may always send along a document the run made; a workflow cannot simply send along other files of the account.

Calculating and formatting: data.format, never the AI

Never let the AI calculate or work out dates. Use data.format:

  • a date for a system as iso_date (2026-10-08) or iso;
  • a due date with add_time (for example 14 days after today);
  • an amount with calculate and round;
  • a list as text with join, or the number with count.

If an ai.transform pulls a date or amount out of free text, put it through data.format first before you give it to a system. Details in Building blocks: AI and editing.

Example: report of a recording to the dossier

After a recorded advice conversation, the workflow writes a report, has the adviser check it, makes a PDF of it and proposes putting it in the customer’s dossier.

{
  "trigger": { "event": "recording.transcribed", "conditions": [ { "path": "trigger.partyId", "op": "exists" } ] },
  "steps": [
    { "id": "verslag", "label": "Write the conversation report", "block": "ai.transform",
      "inputs": { "instruction": "Write a businesslike report with the headings Situation, Agreements and Next steps.",
                  "input": { "transcript": "{{trigger.recording.transcript}}" },
                  "output": { "type": "object", "properties": { "text": { "type": "string" } } } },
      "next": "controle", "onError": "handmatig" },
    { "id": "controle", "label": "Have the adviser check the report", "block": "human.request",
      "inputs": { "title": "Check the report", "exits": ["approve", "reject"],
                  "exitLabels": { "approve": "Correct", "reject": "Do not use" },
                  "fields": { "type": "object", "properties": { "verslag": { "type": "string", "title": "Report" } } },
                  "values": { "verslag": "{{verslag.text}}" },
                  "assignee": "{{trigger.recordedByUserId}}" },
      "exits": { "approve": "pdf" } },
    { "id": "pdf", "label": "Make a PDF of the report", "block": "document.create",
      "inputs": { "title": "Conversation report", "text": "{{controle.fields.verslag}}" }, "next": "dossier" },
    { "id": "dossier", "label": "Find the customer's dossier", "block": "record.find",
      "inputs": { "kind": "dossier" }, "exits": { "found": "upload", "several": "upload", "none": "geen-dossier" } },
    { "id": "upload", "label": "Put the report in the dossier", "block": "plugin.action",
      "inputs": { "action": "dossiersysteem/upload_document", "mode": "propose",
                  "input": { "dossierId": "{{dossier.itemId}}", "attachmentId": "{{pdf.attachmentId}}" },
                  "summary": "Put the conversation report in the dossier",
                  "assignee": "{{trigger.recordedByUserId}}" } },
    { "id": "geen-dossier", "label": "Task: dossier missing", "block": "task.create",
      "inputs": { "title": "No dossier found for the report", "assignee": "{{trigger.recordedByUserId}}" } },
    { "id": "handmatig", "label": "Task: make the report by hand", "block": "task.create",
      "inputs": { "title": "Make the report by hand", "text": "{{verslag.error}}", "assignee": "{{trigger.recordedByUserId}}" } }
  ]
}

dossiersysteem/upload_document and the parameter names are examples; take the real ones from the organisation’s list. The plugin action has no exits: after the proposal the run ends, whatever the colleague decides. If you want to do something afterwards, connect executed, rejected, failed or expired.

Example: order status in a fixed message

A customer asks about their order. The workflow finds the order, reads the status and proposes a message.

[
  { "id": "order", "label": "Find the customer's order", "block": "record.find",
    "inputs": { "kind": "order" }, "exits": { "found": "status", "several": "status", "none": "antwoord" } },
  { "id": "status", "label": "Read the status of the order", "block": "record.read",
    "inputs": { "read": "webshop/order_details", "record": "{{order.recordId}}" },
    "exits": { "found": "bericht", "none": "antwoord", "failed": "antwoord" } },
  { "id": "bericht", "label": "Propose the status to the customer", "block": "message.send",
    "inputs": { "message": "Your order {{order.reference}} now has the status {{status.data.status}}.", "mode": "propose" } },
  { "id": "antwoord", "label": "Let the agent answer", "block": "agent.reply", "inputs": {} }
]

This only works in a workflow on message.understood (because of agent.reply). Usually it is better to let the agent look up the order itself with its skills and to use agent.reply; a fixed message like this suits a fixed, frequently asked question.

Good to know

  • All calls happen within the run’s organisation.
  • If the run is about a conversation, the answers of plugin.read and record.read are kept with that conversation, like a lookup on the ticket.
  • Reading changes nothing; so when you try out a workflow, aishaa really reads and you only see data you may see yourself. aishaa never carries out a plugin action when you try out a workflow.
  • When you publish, aishaa does check the form pluginId/operationId, but not whether the action or read exists in the organisation. That only becomes clear when it runs (failed).

Related

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