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

## 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 OUSD on Tempo into the [Sentora OUSD Main vault on Morpho](https://app.morpho.org/tempo/vault/0x0D136e26B4D9e4836fc5cb202baeb49Cb6f5df48/sentora-ousd-main).

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.

**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 OUSD into Earn',
  owner_id: null,
  config: {
    trigger: {
      type: 'deposit',
      assets: {
        mode: 'include',
        values: [{asset: 'ousd', chain: 'tempo'}]
      }
    },
    action: {
      type: 'earn_deposit',
      vault_id: process.env.PRIVY_EARN_VAULT_ID!
    }
  }
});
```

**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 OUSD into Earn\",
    \"owner_id\": null,
    \"config\": {
      \"trigger\": {
        \"type\": \"deposit\",
        \"assets\": {
          \"mode\": \"include\",
          \"values\": [{\"asset\": \"ousd\", \"chain\": \"tempo\"}]
        }
      },
      \"action\": {
        \"type\": \"earn_deposit\",
        \"vault_id\": \"$PRIVY_EARN_VAULT_ID\"
      }
    }
  }"
```

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

**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!]
  }
});
```

**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\"]}"
```

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.

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


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