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

# Automation lifecycle

> Understand wallet automation matching, execution statuses, and wallet action outcomes.

Privy creates an automation execution after a trigger is matched on an enabled attachment. The execution records why the automation ran and links to the wallet action that it executed.

## Execution flow

```mermaid theme={"system"}
flowchart LR
    pending --> triggered
    pending --> failed
    pending --> skipped
    triggered --> completed
    triggered --> failed
```

| Status      | Terminal | Description                                                                                           |
| ----------- | -------- | ----------------------------------------------------------------------------------------------------- |
| `pending`   | No       | Privy matched the deposit and is preparing the wallet action.                                         |
| `triggered` | No       | Privy created the wallet action and submitted it for processing.                                      |
| `completed` | Yes      | The linked wallet action completed successfully.                                                      |
| `failed`    | Yes      | Preparation or the linked wallet action failed. Inspect `failure_reason` and the action.              |
| `skipped`   | Yes      | The trigger matched, but no action was needed. This can occur if another automation already executed. |

## Relationship to wallet actions

The execution's `wallet_action_id` identifies the action created by the automation. The wallet action contains the detailed onchain lifecycle, including steps and transaction identifiers.

The [`wallet_automation.submitted`](/controls/automations/webhooks) webhook is emitted when the execution reaches `triggered`. It does not indicate that the swap completed.

To observe the final outcome:

1. Read `action_id` from the submitted webhook or `wallet_action_id` from the execution.
2. Fetch the [wallet action status](/wallets/actions/status).
3. Subscribe to the corresponding [`wallet_action.*` events](/wallets/actions/webhooks#swap).

## List executions

Use `GET /v1/wallet_automations/executions` to list executions across the app. Pass `wallet_id` to restrict results to one source wallet.

<Tabs>
  <Tab title="cURL">
    ```bash theme={"system"}
    curl --request GET "https://api.privy.io/v1/wallet_automations/executions?wallet_id=$WALLET_ID&limit=25" \
      --user "$PRIVY_APP_ID:$PRIVY_APP_SECRET" \
      --header "privy-app-id: $PRIVY_APP_ID"
    ```
  </Tab>

  <Tab title="Node SDK">
    ```ts {skip-check} theme={"system"}
    import {PrivyClient} from '@privy-io/node';

    const privy = new PrivyClient({
      appId: process.env.PRIVY_APP_ID!,
      appSecret: process.env.PRIVY_APP_SECRET!
    });

    const executions = [];

    for await (const execution of privy.walletAutomations().listExecutions({
      wallet_id: process.env.WALLET_ID!,
      limit: 100
    })) {
      executions.push(execution);
    }
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={"system"}
    import os
    import requests

    app_id = os.environ["PRIVY_APP_ID"]
    params = {"wallet_id": os.environ["WALLET_ID"], "limit": 100}
    executions = []

    while True:
        response = requests.get(
            "https://api.privy.io/v1/wallet_automations/executions",
            auth=(app_id, os.environ["PRIVY_APP_SECRET"]),
            headers={"privy-app-id": app_id},
            params=params,
        )
        response.raise_for_status()
        page = response.json()
        executions.extend(page["data"])

        if not page["next_cursor"]:
            break
        params["cursor"] = page["next_cursor"]
    ```
  </Tab>
</Tabs>

Results are ordered from newest to oldest. The Node SDK automatically requests subsequent pages during iteration, and the Python example explicitly follows `next_cursor`. With cURL, pass the returned `next_cursor` as `cursor` in the next request until it is `null`.

Each execution includes:

* The source `wallet_id` and matched `automation_attachment_id`.
* The triggering information (e.g. transaction, block, chain, and asset).
* The linked `wallet_action_id` after submission.
* Status timestamps and an optional `failure_reason`.

## Delivery and concurrency

Privy deduplicates repeated delivery of the same detected triggers. Apps should also process webhook deliveries idempotently by `trigger_id`.

Only one automation runs for a wallet at a time. If another matching trigger arrives while the first execution is executing, the later execution can become `skipped` because the remaining balance is zero.

## Troubleshooting

| Result                     | What to inspect                                                                                  |
| -------------------------- | ------------------------------------------------------------------------------------------------ |
| No execution               | Confirm the automation and attachment are enabled and the trigger matches the asset filter.      |
| `skipped`                  | Check whether an earlier execution already swept the balance.                                    |
| `failed` without an action | Inspect `failure_reason`, supported assets and chains, balance availability, and authorization.  |
| `failed` with an action    | Fetch the wallet action with steps and inspect its policy, simulation, and onchain failure data. |
