# Monitoring Power Automate runs

Read a flow's run history, read one run, cancel a run that is still going and resubmit one that failed.

Each time a flow is triggered, Power Automate records a run. This page shows how a Python service works with the runs of a flow:

1. Reading the run history and picking out the runs of one status
2. Reading one run
3. Cancelling a run that is still going
4. Resubmitting a run that failed

## Connection and IDs {#connection-and-ids}

The app registration, the Power Automate connection in the Zato Dashboard and the flow ID are the same as in the [tutorial](https://zato.io/docs/dev/examples/cloud/power-automate/tutorial.html), so set them up as described there first.

## Reading the run history {#reading-the-run-history}

[`conn.list_runs`](https://zato.io/docs/dev/examples/cloud/power-automate/api/runs.html#list_runs) returns the runs of a flow, newest first. The runs are under `value`, each run's ID is its `name`, and its status and times are under `properties`. The service below takes a status from its input and returns the runs that have it.

```python
# -*- coding: utf-8 -*-

# Zato
from zato.server.service import Service

class ListRunsByStatus(Service):

    name = 'power-automate.list-runs-by-status'
    input = 'status'

    def handle(self):

        flow_id = '8f3c1a2e-5b7d-4e9a-b6c0-2d4f7a9e1c35'

        conn = self.microsoft.power_platform['Zato Power Automate']

        response = conn.list_runs(flow_id)

        runs = []
        for run in response['value']:
            if run['properties']['status'] == self.request.input.status:
                runs.append({
                    'id': run['name'],
                    'started': run['properties']['startTime'],
                })

        self.response.payload = {'runs': runs}
```

Invoked with `{"status": "Failed"}`, the service returns:

```json
{"runs": [
  {"id": "08584623197582406521456132557CU12", "started": "2026-09-27T14:03:19.7140252Z"}
]}
```

## Reading one run {#reading-one-run}

[`conn.get_run`](https://zato.io/docs/dev/examples/cloud/power-automate/api/runs.html#get_run) returns one run with its status, its start and end times and, for a run that failed, the error under `properties.error`.

```python
# -*- coding: utf-8 -*-

# Zato
from zato.server.service import Service

class GetRun(Service):

    name = 'power-automate.get-run'
    input = 'run_id'

    def handle(self):

        flow_id = '8f3c1a2e-5b7d-4e9a-b6c0-2d4f7a9e1c35'

        conn = self.microsoft.power_platform['Zato Power Automate']

        run = conn.get_run(flow_id, self.request.input.run_id)

        self.response.payload = {
            'status': run['properties']['status'],
            'started': run['properties']['startTime'],
            'ended': run['properties']['endTime'],
        }
```

```json
{"status": "Failed", "started": "2026-09-27T14:03:19.7140252Z", "ended": "2026-09-27T14:03:21.0021873Z"}
```

## Cancelling a run {#cancelling-a-run}

[`conn.cancel_run`](https://zato.io/docs/dev/examples/cloud/power-automate/api/runs.html#cancel_run) stops a run whose status is `Running`, and returns nothing.

```python
# -*- coding: utf-8 -*-

# Zato
from zato.server.service import Service

class CancelRun(Service):

    name = 'power-automate.cancel-run'
    input = 'run_id'

    def handle(self):

        flow_id = '8f3c1a2e-5b7d-4e9a-b6c0-2d4f7a9e1c35'

        conn = self.microsoft.power_platform['Zato Power Automate']

        conn.cancel_run(flow_id, self.request.input.run_id)

        self.response.payload = {'run_id': self.request.input.run_id, 'status': 'Cancelled'}
```

## Resubmitting a failed run {#resubmitting-a-failed-run}

[`conn.resubmit_run`](https://zato.io/docs/dev/examples/cloud/power-automate/api/runs.html#resubmit_run) runs the flow again with the same trigger input the original run had, and returns nothing. The service below combines it with the filter from the first example, resubmitting every run that failed.

```python
# -*- coding: utf-8 -*-

# Zato
from zato.server.service import Service

class ResubmitFailedRuns(Service):

    name = 'power-automate.resubmit-failed-runs'

    def handle(self):

        flow_id = '8f3c1a2e-5b7d-4e9a-b6c0-2d4f7a9e1c35'

        conn = self.microsoft.power_platform['Zato Power Automate']

        response = conn.list_runs(flow_id)

        resubmitted = []
        for run in response['value']:
            if run['properties']['status'] == 'Failed':
                conn.resubmit_run(flow_id, run['name'])
                resubmitted.append(run['name'])

        self.response.payload = {'resubmitted': resubmitted}
```

```json
{"resubmitted": ["08584623197582406521456132557CU12"]}
```

Each resubmission is a new run in the history, the failed one stays there with its status unchanged.

## See also {#see-also}

- [Power Automate API - Runs](https://zato.io/docs/dev/examples/cloud/power-automate/api/runs.html) - list\_runs, get\_run, cancel\_run and resubmit\_run, with every parameter and the run statuses
- [Triggering Power Automate flows](https://zato.io/docs/dev/examples/cloud/power-automate/triggering-flows.html) - Triggering a flow to create a run
- [Managing Power Automate flows](https://zato.io/docs/dev/examples/cloud/power-automate/managing-flows.html) - Listing flows and turning them on and off

## Learn more {#learn-more}

- [Development documentation](https://zato.io/docs/dev/) - The complete reference for writing services
- [Requests and responses](https://zato.io/docs/dev/request-response/) - What a service receives, what it returns and how both are structured
- [Integration examples](https://zato.io/docs/dev/examples/) - Ready-made code for the systems you are likely to connect to
- [IDE and debugging](https://zato.io/docs/dev/ide/) - Write services in the Dashboard or in your own editor
- [Data models](https://zato.io/docs/dev/model/) - Declare inputs and outputs and have them validated for you
- [In-depth API tutorial](https://zato.io/tutorials/main/01.html) - The full platform tutorial, from installation to production patterns
