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

# Automate Earn deposits

> Automatically deposit a wallet balance into an Earn vault when funds arrive.

An Earn deposit automation moves a wallet's full balance of one asset into a configured Earn vault when a matching deposit arrives. The app creates one reusable automation for each vault, then attaches the appropriate automation to each wallet.

<Warning>
  Run these examples from a trusted server. Never expose the Privy app secret in client-side code.
</Warning>

## Prerequisites

The integration requires:

* A Privy app ID and app secret.
* A configured [Earn vault](/wallets/actions/earn/setup) and its `vault_id`.
* A source [Privy wallet](/wallets/overview). Imported or previously exported wallets cannot receive automation attachments.
* The vault's underlying asset and chain. The automation trigger must match both.
* An authorization signature when the source wallet has an [owner](/controls/authorization-keys/owners/overview).

## 1. Create the automation

Create an app-scoped automation with `POST /v1/wallet_automations`. The example below deposits pathUSD on Tempo into a pathUSD vault.

The trigger must use `include` mode with exactly one asset. The asset and chain must match the configured vault. The required `owner_id` controls changes to the shared automation definition.

<Tabs>
  <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 automation = await privy.walletAutomations().create({
      name: 'Deposit Tempo PathUSD into Earn',
      owner_id: null,
      config: {
        trigger: {
          type: 'deposit',
          assets: {
            mode: 'include',
            values: [{asset: 'pathusd', chain: 'tempo'}]
          }
        },
        action: {
          type: 'earn_deposit',
          vault_id: process.env.PRIVY_EARN_VAULT_ID!
        }
      }
    });
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={"system"}
    curl --request POST 'https://api.privy.io/v1/wallet_automations' \
      --user "$PRIVY_APP_ID:$PRIVY_APP_SECRET" \
      --header "privy-app-id: $PRIVY_APP_ID" \
      --header 'content-type: application/json' \
      --data "{
        \"name\": \"Deposit Tempo PathUSD into Earn\",
        \"owner_id\": null,
        \"config\": {
          \"trigger\": {
            \"type\": \"deposit\",
            \"assets\": {
              \"mode\": \"include\",
              \"values\": [{\"asset\": \"pathusd\", \"chain\": \"tempo\"}]
            }
          },
          \"action\": {
            \"type\": \"earn_deposit\",
            \"vault_id\": \"$PRIVY_EARN_VAULT_ID\"
          }
        }
      }"
    ```
  </Tab>
</Tabs>

Save the returned automation `id`. New automation definitions are enabled by default.

## 2. Attach it to a wallet

Attach the automation to each wallet that should deposit into the vault. Earn deposit automations do not accept per-wallet `params`.

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

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

The authorization signature must cover the exact attach request. Omit `authorization_context` and the `privy-authorization-signature` header for an ownerless wallet.

## 3. Send a matching deposit

Send the vault's underlying asset to the source wallet. Privy detects the transfer, reads the wallet's current asset balance, and submits an `earn_deposit` wallet action for the full balance.

<Warning>
  The automation deposits the wallet's full current balance, not only the latest transfer. Earlier
  funds held by the wallet can be included.
</Warning>

Attaching an automation does not process a balance already held by the wallet. Send a new matching deposit or [reindex the asset](/wallets/automations/lifecycle#recover-a-missed-or-failed-deposit) to process that balance.

For multi-chain or different-asset funding, an app can chain a crypto deposit account with an Earn deposit automation. The crypto deposit account accepts funds on other chains or in other assets and swaps them into the vault's underlying asset in a destination wallet. Attach the Earn deposit automation to that destination wallet to sweep the funds into the vault. This lets the app accept assets across chains and deposit them into a vault. Learn more about [crypto deposit accounts](/wallets/funding/crypto-deposits/overview).

## 4. Observe the deposit

Subscribe to [`wallet_automation.submitted`](/wallets/automations/webhooks) to receive the automation execution ID and generated wallet action ID. Use the action ID to track the [wallet action lifecycle](/wallets/actions/lifecycle).

The [`wallet_action.earn_deposit.succeeded`](/api-reference/webhooks/wallet-action/earn-deposit/succeeded) webhook confirms that the assets entered the vault. Failed or rejected Earn actions emit the corresponding [Earn webhooks](/wallets/actions/earn/webhooks).

## Withdraw assets

Use the [Earn withdrawal action](/wallets/actions/earn/withdraw) to return assets and accrued yield to the wallet. Privy recognizes transfers from the configured vault and does not redeposit them automatically.

## Handle errors

Setup requests can fail when:

* The vault does not belong to the app.
* The trigger does not match exactly one underlying vault asset and chain.
* The wallet-owner authorization signature is missing or does not cover the exact attach request.
* The automation includes attachment `params`.

An automation can still fail during execution because of an insufficient balance, policy rejection, unavailable vault, or onchain failure. Inspect the execution's `failure_reason` and generated wallet action. After correcting a pre-action failure, [reindex the asset](/wallets/automations/lifecycle#recover-a-missed-or-failed-deposit).
