> ## Documentation Index
> Fetch the complete documentation index at: https://docs.indm.social/llms.txt
> Use this file to discover all available pages before exploring further.

# Read how an automation is doing

> Pull your live automations' results into a dashboard, a sheet or a daily digest.

Your automations are working whether or not you're watching. This recipe brings their results to where you already look: a weekly report for a client, a row in a sheet, a message in your team's channel.

A `read` key is all it needs, and that's the key to give a reporting job.

## The numbers

[Get automation stats](https://docs.indm.social/api-reference/automations/get-automation-stats.md) counts what one automation did over a window of `days`, ending now:

| Field | What it counts |
| - | - |
| `times_triggered` | Comments that matched a keyword and fired the automation. |
| `messages_sent` | Messages Instagram accepted. |
| `messages_failed` | Messages Instagram refused. |
| `messages_waiting` | Messages queued and not yet sent. |

All four are totals for the automation. Nothing about any individual person comes back.

## Every live automation, last 7 days

```javascript Node theme={null}
const API = "https://api.indm.social/v1";
const headers = { Authorization: `Bearer ${process.env.INDM_API_KEY}` };
const get = (path) => fetch(API + path, { headers }).then((r) => r.json());

async function weeklyReport() {
  const accounts = await get("/accounts");
  const handle = Object.fromEntries(accounts.data.map((a) => [a.id, a.username]));
  const rows = [];
  let cursor = null;
  do {
    const page = await get(
      `/automations?status=live&limit=100${cursor ? `&cursor=${cursor}` : ""}`,
    );
    for (const a of page.data) {
      const s = await get(`/automations/${a.id}/stats?days=7`);
      rows.push({
        automation: a.name,
        account: handle[a.account_id],
        triggered: s.times_triggered,
        sent: s.messages_sent,
        failed: s.messages_failed,
        waiting: s.messages_waiting,
      });
    }
    cursor = page.has_more ? page.next_cursor : null;
  } while (cursor);
  console.table(rows);
}
```

```python Python theme={null}
import os
import requests

API = "https://api.indm.social/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['INDM_API_KEY']}"}


def get(path, **params):
    return requests.get(API + path, headers=HEADERS, params=params).json()


def weekly_report():
    handle = {a["id"]: a["username"] for a in get("/accounts")["data"]}
    rows, cursor = [], None
    while True:
        params = {"status": "live", "limit": 100}
        if cursor:
            params["cursor"] = cursor
        page = get("/automations", **params)
        for a in page["data"]:
            s = get(f"/automations/{a['id']}/stats", days=7)
            rows.append({
                "automation": a["name"],
                "account": handle[a["account_id"]],
                "triggered": s["times_triggered"],
                "sent": s["messages_sent"],
                "failed": s["messages_failed"],
                "waiting": s["messages_waiting"],
            })
        if not page["has_more"]:
            break
        cursor = page["next_cursor"]
    for row in rows:
        print(row)
```

Each automation costs one stats call, so a large workspace adds up. Pace a big report by the [rate limit headers](https://docs.indm.social/rate-limits.md#headers).

## Reading them well

* **`messages_sent` can be higher than `times_triggered`.** One comment can lead to more than one message: an opener and then the link, or a follow-up hours later. Compare messages with messages, and comments with comments.
* **`messages_waiting` isn't a fault.** Each account sends at a steady pace so Instagram keeps trusting it. When a post takes off, messages queue and drain. [Get account health](https://docs.indm.social/api-reference/accounts/get-account-health.md) says how long the queue takes to clear.
* **For a failure share, divide failed by failed plus sent.** That reads as "of the messages Instagram answered, how many did it refuse".
* **When `messages_failed` climbs, ask the account.** [Get account health](https://docs.indm.social/api-reference/accounts/get-account-health.md) lists what Instagram has been refusing and how often, and whether the connection itself needs attention.
* **Triggered but nothing sent?** Check the account's health first. A paused connection sends nothing until it's reconnected, and `automations_that_cannot_fire` names any live automation set up so it can never trigger.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.