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

Wallet create, get, and list responses can also include an `automations` array. Each entry contains the automation `id` and an `enabled` value that reflects both the definition and attachment state.

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 an automation

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

Fields omitted from the request remain unchanged. Setting `name` or `owner_id` to `null` clears that field. The existing owner must authorize updates to an owned automation.

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

### Pause or resume an automation

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

Automation responses represent this state as `status: "enabled" | "disabled"`. Update requests use the boolean `enabled` field.

## Matching precedence

A wallet can have multiple attached automations. Privy evaluates enabled attachments from oldest to newest and runs only the first matching automation. Privy does not try a lower-priority match if the selected automation fails.

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

Attaching an automation that is already attached updates the existing attachment and preserves its priority. Detaching and later reattaching creates a new attachment that is evaluated after older attachments.

## Update attachment parameters

Call the attach endpoint again with the existing automation ID to change its per-wallet parameters. For a swap automation, this updates `destination_address` without creating a duplicate attachment.

The request's single `params` object applies to every automation ID. Batch together only automations that accept the same parameters. Earn deposit automations do not accept `params`.

## Detach from a wallet

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

Detach requests are all or nothing. If any requested automation is not attached to the wallet, the request fails without detaching the others.

<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. The exported wallet cannot receive new automation attachments.
</Info>

## Delete an automation

Deleting an automation permanently removes its definition and all attachments. Existing execution and wallet action records remain, but a deleted attachment can no longer identify its automation through the execution list response. Persist the IDs from submitted webhooks when long-term correlation is required.

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 or update to assign a [key quorum](/controls/key-quorum/overview) as the automation owner. The existing owner must authorize changing or clearing `owner_id`.

| 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

* Imported wallets and wallets previously exported from Privy cannot receive automation attachments.
* 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.
