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

# Audit trail & exports

> List a business account's audit trail and export it to a CSV file.

> [!NOTE]
>
> Business Accounts are in **early access**. See [Business Accounts](https://www.dynamic.xyz/docs/business-accounts/accounts.md) for the model.

Every business account keeps an append-only audit trail that records account-level actions: who did what, and when. Entries are returned newest first, and only the owner and admins can read the trail. A call from a non-member returns a 404.

## List activity

`listBusinessAccountActivity` returns one page of entries and a `nextCursor`. Pass that cursor back to fetch the next page; `nextCursor` is `null` at the end of the trail.

| Parameter | Type | Description |
| - | - | - |
| `businessAccountId` | `string` | The business account to read. Required. |
| `limit` | `number` | Maximum entries per page, between 1 and 100. Defaults to 50. |
| `cursor` | `string` | A previous page's `nextCursor`. |

**JavaScript**

```javascript theme={"system"}
import {
  listBusinessAccountActivity,
  type BusinessAccountActivityEntry,
} from '@dynamic-labs-sdk/client/waas';

const entries: BusinessAccountActivityEntry[] = [];
let cursor = undefined;
do {
  const list = await listBusinessAccountActivity({ businessAccountId, cursor });
  entries.push(...list.entries);
  cursor = list.nextCursor ?? undefined;
} while (cursor);
```

**React**

```tsx theme={"system"}
import { useListBusinessAccountActivity } from '@dynamic-labs-sdk/react-hooks';

const { data: activity, isLoading } = useListBusinessAccountActivity({
  businessAccountId,
});
// activity?.entries holds the page, activity?.nextCursor the cursor for the next page
```

Each entry is a `BusinessAccountActivityEntry`:

| Field | Type | Description |
| - | - | - |
| `id` | `string` | Unique entry ID. |
| `businessAccountId` | `string` | The account the action was taken on. |
| `action` | `BusinessAccountActionType` | The kind of action, for example `memberAdded`. |
| `takenByUserId` | `string \| null` | The acting user's ID. `null` when the action was system-triggered. |
| `takenByEmail` | `string \| null` | The actor's verified email, when they have one. |
| `metadata` | `object` | Per-action context, such as target identifiers and changed values. |
| `createdAt` | `Date` | When the action happened. |

### Action types

`BusinessAccountActionType` covers the whole trail, grouped here by area:

* Account: `businessAccountCreated`, `businessAccountRenamed`, `businessAccountDeleted`
* Members: `memberAdded`, `memberRoleChanged`, `memberRemoved`, `ownershipTransferred`
* Signers: `signerAdded`, `signerRevoked`, `signerExpired`
* Wallets: `walletAttached`, `walletDetached`, `walletTransferred`
* Key shares: `shareSetCreated`, `shareSetReshared`, `shareSetRefreshed`, `shareSetRevoked`
* Governance and roles: `governanceChanged`, `roleDefined`, `roleDeleted`
* Proposals: `proposalCreated`, `proposalApproved`, `proposalApprovalWithdrawn`, `proposalVetoed`, `proposalExecuted`, `proposalExpired`

## Export the trail to CSV

`downloadBusinessAccountActivityExport` creates an activity export, polls until it is ready, and starts a browser download of the CSV file. It runs in the browser only.

| Parameter | Type | Description |
| - | - | - |
| `businessAccountId` | `string` | The business account to export. Required. |
| `from` | `string` | Only include entries at or after this ISO 8601 timestamp. |
| `to` | `string` | Only include entries at or before this ISO 8601 timestamp. |
| `actionTypes` | `BusinessAccountActionType[]` | Only include these action types. |
| `pollIntervalMs` | `number` | How often to re-check export status while waiting. Defaults to 2000. |
| `timeoutMs` | `number` | Maximum time to wait for the export to complete. Defaults to 120000. |

**JavaScript**

```javascript theme={"system"}
import { downloadBusinessAccountActivityExport } from '@dynamic-labs-sdk/client/waas';

await downloadBusinessAccountActivityExport({
  businessAccountId,
  from: '2026-01-01T00:00:00.000Z',
  actionTypes: ['memberAdded', 'signerAdded'],
});
```

**React**

```tsx theme={"system"}
import { useDownloadBusinessAccountActivityExport } from '@dynamic-labs-sdk/react-hooks';

const ExportActivity = ({ businessAccountId }) => {
  const { mutate, isPending, isSuccess } =
    useDownloadBusinessAccountActivityExport();
  return (
    <button
      disabled={isPending}
      onClick={() => mutate({ businessAccountId })}
    >
      {isSuccess ? 'Download started' : 'Export activity CSV'}
    </button>
  );
};
```

The call throws when the export cannot be delivered. The errors are exported from `@dynamic-labs-sdk/client`:

| Error | Thrown when |
| - | - |
| `BrowserDownloadUnavailableError` | There is no browser document, for example during server-side rendering. |
| `BusinessAccountActivityExportTimeoutError` | The export is still pending when `timeoutMs` elapses. |
| `BusinessAccountActivityExportFailedError` | The export finishes in a state other than completed. |
| `BusinessAccountActivityExportDownloadUrlError` | The completed export has a missing or invalid download URL. |

A `from` or `to` value that is not a valid ISO 8601 timestamp throws a `TypeError` before the export is created.

## Related

> **[Members & roles](https://www.dynamic.xyz/docs/javascript/reference/business-accounts/members-and-roles.md)**
>
> Roles and membership determine who can read the trail.

> **[Governance](https://www.dynamic.xyz/docs/javascript/reference/business-accounts/governance.md)**
>
> Proposal activity appears in the trail alongside account changes.


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