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

# Monitoring

> Track transactions and monitor account state in real-time

# Monitoring

After executing a plan, you need to know when it confirms. Legend offers two approaches: polling activities and long-polling events.

## Polling activities

The simplest approach. After executing a plan, poll the activities endpoint until you see your transaction:

<CodeGroup>
  ```typescript TypeScript theme={null}
  let confirmed = false;

  for (let i = 0; i < 30; i++) {
    const { activities } = await client.accounts.activities(account.account_id);

    if (activities.length > 0 && activities[0].activity_status === "confirmed") {
      console.log("Transaction confirmed!");
      confirmed = true;
      break;
    }

    await new Promise((r) => setTimeout(r, 2000));
  }
  ```

  ```python Python theme={null}
  import asyncio

  confirmed = False

  for _ in range(30):
      result = await client.accounts.activities(account["account_id"])
      activities = result["activities"]

      if activities and activities[0]["activity_status"] == "confirmed":
          print("Transaction confirmed!")
          confirmed = True
          break

      await asyncio.sleep(2)
  ```

  ```rust Rust theme={null}
  use std::time::Duration;
  use tokio::time::sleep;

  let mut confirmed = false;

  for _ in 0..30 {
      let result = client
          .accounts()
          .activities(&account.account_id)
          .await?;

      if let Some(activity) = result.activities.first() {
          if activity.activity_status == "confirmed" {
              println!("Transaction confirmed!");
              confirmed = true;
              break;
          }
      }

      sleep(Duration::from_secs(2)).await;
  }
  ```
</CodeGroup>

This works, but makes many requests. For production use, prefer long-polling.

## Long-polling events

The events endpoint with `poll=true` holds the connection open until something happens — no wasted requests:

<CodeGroup>
  ```typescript TypeScript theme={null}
  let cursor = 0;

  // Wait for the next event
  const { events, cursor: newCursor } = await client.accounts.events(
    account.account_id,
    { since: cursor, poll: true }
  );

  for (const event of events) {
    if (event.event_type === "activity_updated") {
      console.log(`Activity ${event.data.activity_id}: ${event.data.activity_status}`);
    }
  }

  cursor = newCursor;
  ```

  ```python Python theme={null}
  cursor = 0

  # Wait for the next event
  result = await client.accounts.events(
      account["account_id"],
      since=cursor,
      poll=True,
  )

  for event in result["events"]:
      if event["event_type"] == "activity_updated":
          print(f"Activity {event['data']['activity_id']}: {event['data']['activity_status']}")

  cursor = result["cursor"]
  ```

  ```rust Rust theme={null}
  let mut cursor = 0;

  // Wait for the next event
  let result = client
      .accounts()
      .events(&account.account_id, Some(cursor), Some(true))
      .await?;

  for event in &result.events {
      if event.event_type == "activity_updated" {
          println!(
              "Activity {}: {}",
              event.data.activity_id, event.data.activity_status
          );
      }
  }

  cursor = result.cursor;
  ```
</CodeGroup>

## Continuous monitoring loop

For a service that needs to react to all account changes:

<CodeGroup>
  ```typescript TypeScript theme={null}
  async function monitor(accountId: string) {
    let cursor = 0;

    while (true) {
      try {
        const { events, cursor: newCursor } = await client.accounts.events(
          accountId,
          { since: cursor, poll: true }
        );

        for (const event of events) {
          await handleEvent(event);
        }

        cursor = newCursor;
      } catch (error) {
        console.error("Event polling error, retrying...", error);
        await new Promise((r) => setTimeout(r, 5000));
      }
    }
  }
  ```

  ```python Python theme={null}
  async def monitor(account_id: str):
      cursor = 0

      while True:
          try:
              result = await client.accounts.events(
                  account_id,
                  since=cursor,
                  poll=True,
              )

              for event in result["events"]:
                  await handle_event(event)

              cursor = result["cursor"]
          except Exception as e:
              print(f"Event polling error, retrying... {e}")
              await asyncio.sleep(5)
  ```

  ```rust Rust theme={null}
  async fn monitor(client: &LegendPrime, account_id: &str) -> Result<(), Box<dyn std::error::Error>> {
      let mut cursor = 0;

      loop {
          match client
              .accounts()
              .events(account_id, Some(cursor), Some(true))
              .await
          {
              Ok(result) => {
                  for event in &result.events {
                      handle_event(event).await;
                  }
                  cursor = result.cursor;
              }
              Err(e) => {
                  eprintln!("Event polling error, retrying... {e}");
                  sleep(Duration::from_secs(5)).await;
              }
          }
      }
  }
  ```
</CodeGroup>

## Which approach to use

| Scenario                        | Recommendation            |
| ------------------------------- | ------------------------- |
| Wait for one transaction        | Poll activities in a loop |
| Monitor an account continuously | Long-poll events          |
| Dashboard with live updates     | Long-poll events          |
| Batch job checking final state  | Single activities fetch   |
