🚀 New batches open: Advanced Excel • Power BI • SQL • AI for Analytics — Book a free demo

Day 2 — Triggers - what starts a flow

Pick the wrong trigger and you will fight the flow forever. Pick the right one and half the work disappears.

The three kinds

KindStarts whenTypical use
AutomatedSomething happens in a systemA form is submitted, an email arrives, a SharePoint item is created
InstantA person presses a buttonA manual button in the mobile app, or from Power Apps
ScheduledThe clockEvery weekday at 9am, the first of the month
One trigger per flow. Always. There is no "run this when a form is submitted or at 9am". If you need both, build two flows, and put the shared work in a child flow they both call.

The trigger hands you data

Whatever started the flow brings its data with it. triggerBody() is how you reach it, and ?['FieldName'] picks one field out.

{
  "trigger": {
    "name": "When a new response is submitted",
    "type": "automated",
    "body": {
      "ResponseId": "R-1042",
      "Name": "Rahul Verma",
      "Email": "rahul@example.com",
      "Course": "Power BI",
      "Experience": 4,
      "SubmittedOn": "2026-03-18T09:12:00Z"
    }
  },
  "actions": [
    { "name": "Everything", "type": "Compose", "input": "@triggerBody()" },
    { "name": "Name only", "type": "Compose", "input": "@triggerBody()?['Name']" },
    { "name": "Years", "type": "Compose", "input": "@triggerBody()?['Experience']" },
    { "name": "A field that is not there", "type": "Compose", "input": "@triggerBody()?['Phone']" }
  ]
}

Look at the last one. Asking for a field that does not exist gives you null, not an error - because of the ?. Day 4 goes into exactly why that question mark matters so much.

Scheduled flows

A recurrence trigger has no useful body - the clock does not hand you anything. Everything the flow needs, it fetches itself.

{
  "trigger": {
    "name": "Every weekday at 9am",
    "type": "Recurrence",
    "body": {}
  },
  "actions": [
    { "name": "Today", "type": "Compose", "input": "@utcNow()" },
    { "name": "Readable", "type": "Compose", "input": "@formatDateTime(utcNow(), 'dddd dd MMM yyyy')" },
    { "name": "India time", "type": "Compose",
      "input": "@convertTimeZone(utcNow(), 'UTC', 'India Standard Time', 'HH:mm')" },
    { "name": "Report title", "type": "Compose",
      "input": "Daily MIS - @{formatDateTime(utcNow(), 'dd MMM yyyy')}" }
  ]
}
The clock is UTC, not your clock Power Automate runs on UTC. A recurrence set to 9:00 fires at 2:30pm in India. Either set the time zone on the trigger itself, or set it to 03:30 UTC and comment why. This catches everybody once, usually in front of a client.
The playground’s clock is frozen at 18 March 2026, 09:30 UTC so the examples give the same answer every time. Notice the India time above comes out at 15:00 - that is the 5 hours 30 minutes.

Trigger conditions - do not start at all

The obvious way to ignore some rows is a Condition as the first action. It works, but the flow still runs - it appears in your run history, it uses your daily quota, and the history fills up with runs that did nothing.

A trigger condition stops it before it starts. In this playground you can see the same idea with an early Terminate.

{
  "trigger": { "type": "automated",
    "body": { "Name": "Meera", "Course": "SQL", "Amount": 800 } },
  "actions": [
    {
      "name": "Worth processing?",
      "type": "Condition",
      "expression": "@greaterOrEquals(triggerBody()?['Amount'], 1000)",
      "yes": [
        { "name": "Carry on", "type": "Compose", "input": "Processing this enrolment" }
      ],
      "no": [
        { "name": "Stop here", "type": "Terminate", "status": "Cancelled",
          "message": "Amount below the threshold" }
      ]
    },
    { "name": "Later work", "type": "Compose", "input": "This runs only if we did not stop" }
  ]
}

Run it. The flow takes the If no branch, stops, and "Later work" is marked Skipped. Change the Amount to 5000 and run again to see the other path.

Choosing the trigger

Three questions What exactly is the event? "When a row is added" is not the same as "when a row changes".
How soon must it react? Instant reaction needs an automated trigger. "Some time today" can be a schedule, which is far cheaper and easier to debug.
What if it fires twice? Some triggers fire again on an edit. If your flow adds a row every time, you will get duplicates. Design for it.

Try these yourself

  1. Write a flow whose trigger body has five fields, and compose three of them into a sentence.
  2. Print the current date in dd/MM/yyyy and in dddd dd MMMM yyyy.
  3. Work out what time a 9:00 UTC recurrence fires in India.
  4. Build a flow that terminates early when a field is empty.
  5. Give an example of a job that suits a scheduled trigger better than an automated one.