Skip to main content

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:
let confirmed = false;

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

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

  await new Promise((r) => setTimeout(r, 2000));
}
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:
let cursor = 0;

// Wait for the next event
const { events, cursor: newCursor } = await client.accounts.events(
  account.external_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;

Continuous monitoring loop

For a service that needs to react to all account changes:
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));
    }
  }
}

Which approach to use

ScenarioRecommendation
Wait for one transactionPoll activities in a loop
Monitor an account continuouslyLong-poll events
Dashboard with live updatesLong-poll events
Batch job checking final stateSingle activities fetch