> ## 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.

# Manage automations

> List, update, pause, attach, detach, and delete wallet automations safely.

Automation definitions are app-scoped and reusable. Attachments activate those definitions for individual wallets.

## List automations

List all definitions with `GET /v1/wallet_automations`. Pass `wallet_id` to return only automations attached to one wallet.

The Node SDK and Python examples initialize reusable clients here. The remaining examples on this page reuse those clients.

<Tabs>
  <Tab title="cURL">
    ```bash theme={"system"}
    curl --request GET "https://api.privy.io/v1/wallet_automations?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 automations = [];

    for await (const automation of privy.walletAutomations().list({
      wallet_id: process.env.WALLET_ID!,
      limit: 100
    })) {
      automations.push(automation);
    }
    ```
  </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}
    automations = []

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

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

## Update or pause an automation

`PATCH /v1/wallet_automations/{automation_id}` can update `name`, `config`, or `enabled`.

<Tabs>
  <Tab title="cURL">
    ```bash theme={"system"}
    curl --request PATCH \
      "https://api.privy.io/v1/wallet_automations/$AUTOMATION_ID" \
      --user "$PRIVY_APP_ID:$PRIVY_APP_SECRET" \
      --header "privy-app-id: $PRIVY_APP_ID" \
      --header 'content-type: application/json' \
      --data '{"enabled": false}'
    ```
  </Tab>

  <Tab title="Node SDK">
    ```ts {skip-check} theme={"system"}
    const automation = await privy.walletAutomations().update(process.env.AUTOMATION_ID!, {
      enabled: false
    });
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={"system"}
    response = requests.patch(
        f"https://api.privy.io/v1/wallet_automations/{os.environ['AUTOMATION_ID']}",
        auth=(app_id, os.environ["PRIVY_APP_SECRET"]),
        headers={"privy-app-id": app_id},
        json={"enabled": False},
    )
    response.raise_for_status()
    automation = response.json()
    ```
  </Tab>
</Tabs>

Disabling an automation pauses it for every attached wallet. Attachments remain in place and resume when the automation is enabled again.

<Warning>
  Updating `config` changes the trigger and action for every attached wallet. Create a separate
  automation when only some wallets should adopt the new behavior.
</Warning>

## Matching precedence

A wallet can have multiple attached automations. Privy evaluates enabled attachments from oldest to newest and runs only the first matching automation.

Use non-overlapping asset filters when every route must be unambiguous. If filters intentionally overlap, attach the highest-priority automation first.

Detaching and later reattaching an automation creates a new attachment. The new attachment is evaluated after older attachments.

## Detach from a wallet

Detaching stops selected automations for one wallet without changing their other attachments.

<Tabs>
  <Tab title="cURL">
    ```bash theme={"system"}
    curl --request POST \
      "https://api.privy.io/v1/wallets/$WALLET_ID/automations/detach" \
      --user "$PRIVY_APP_ID:$PRIVY_APP_SECRET" \
      --header "privy-app-id: $PRIVY_APP_ID" \
      --header 'content-type: application/json' \
      --header "privy-authorization-signature: $PRIVY_AUTHORIZATION_SIGNATURE" \
      --data "{\"automation_ids\": [\"$AUTOMATION_ID\"]}"
    ```
  </Tab>

  <Tab title="Node SDK">
    ```ts {skip-check} theme={"system"}
    await privy.wallets().detachAutomations(process.env.WALLET_ID!, {
      automation_ids: [process.env.AUTOMATION_ID!],
      authorization_context: {
        signatures: [process.env.PRIVY_AUTHORIZATION_SIGNATURE!]
      }
    });
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={"system"}
    response = requests.post(
        f"https://api.privy.io/v1/wallets/{os.environ['WALLET_ID']}/automations/detach",
        auth=(app_id, os.environ["PRIVY_APP_SECRET"]),
        headers={
            "privy-app-id": app_id,
            "privy-authorization-signature": os.environ[
                "PRIVY_AUTHORIZATION_SIGNATURE"
            ],
        },
        json={"automation_ids": [os.environ["AUTOMATION_ID"]]},
    )
    response.raise_for_status()
    ```
  </Tab>
</Tabs>

<Info>
  A successful private-key or seed-phrase export also removes all automation attachments from that
  wallet. This prevents an exported wallet from remaining enrolled in previous automation consent.
</Info>

## Delete an automation

Deleting an automation permanently removes its definition and all attachments. Existing execution and wallet action records remain available for auditing.

Use disable when the automation might resume. Use detach to stop it for selected wallets. Delete only when the definition is no longer needed.

<Tabs>
  <Tab title="cURL">
    ```bash theme={"system"}
    curl --request DELETE \
      "https://api.privy.io/v1/wallet_automations/$AUTOMATION_ID" \
      --user "$PRIVY_APP_ID:$PRIVY_APP_SECRET" \
      --header "privy-app-id: $PRIVY_APP_ID"
    ```
  </Tab>

  <Tab title="Node SDK">
    ```ts {skip-check} theme={"system"}
    await privy.walletAutomations().delete(process.env.AUTOMATION_ID!);
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={"system"}
    response = requests.delete(
        f"https://api.privy.io/v1/wallet_automations/{os.environ['AUTOMATION_ID']}",
        auth=(app_id, os.environ["PRIVY_APP_SECRET"]),
        headers={"privy-app-id": app_id},
    )
    response.raise_for_status()
    ```
  </Tab>
</Tabs>

## Advanced: automation ownership

Set `owner_id` during creation to assign a [key quorum](/controls/key-quorum/overview) as the automation owner.

| Operation        | Required authorization                                                                       |
| ---------------- | -------------------------------------------------------------------------------------------- |
| Create or read   | App-secret authentication.                                                                   |
| Update or delete | App-secret authentication and the automation owner's authorization signature, if it has one. |
| Attach or detach | Authorization from the target wallet's owner, when the wallet has one.                       |

The owner protects the shared definition. The wallet owner separately controls whether that definition is attached to their wallet.

## Limits

* An attach or detach request accepts up to 20 automation IDs.
* An `include` or `exclude` filter accepts up to 20 asset specifications in an API request.
* A wallet can have up to 100 automation attachments.
* List endpoints accept `limit` values from 1 through 100 and default to 25.

See the [wallet automation API reference](/api-reference/wallet-automations/create) for request and response schemas.
