# Move money between accounts

URL: /systems/finance/move-money · Id: `guide:move-money`

> Say "move $5,000 to the card balance" or "sweep everything over $20,000 to reserve" and the Treasurer moves it, once or on a standing rule.

Move cash between the [Startup](/business/nouns/startup)'s own accounts, once or on a rule. Money to your bank goes out as a payout: [pay out to your bank](/systems/finance/pay-out-to-my-bank).

Needs: [Open a bank account](/systems/finance/open-a-bank-account) · [Open a bank account](/systems/finance/open-a-bank-account)

**Before it runs**

- You leave the chat: Never: it all happens in the chat.

## What you get
- 1 transfer between two of your cash accounts, matched on both statements (Transaction)
- 1 standing rule, when you ask for one, that moves cash on a schedule (Account)
- 2 lines in your books: cash out of one account, into the other (Entry)

## Your agent does
**For agents**

- Guide: `guide:move-money`, status `beta`. Page: [/systems/finance/move-money.md](/systems/finance/move-money.md).
- Approval: none. Run it when the founder asks.
- Leaves the chat: never.
- Needs first: [Open a bank account](/systems/finance/open-a-bank-account), [Open a bank account](/systems/finance/open-a-bank-account).
- Run: call the steps in order, each through the API, SDK, CLI or MCP tab below; a later step passes the `$id` an earlier one returns. Each value marked example is the sample business’s: pass the founder’s own.

| Step | Verb | Inputs (type, required, this guide’s value) | Returns |
| --- | --- | --- | --- |
| 1 | [`Account.sweep`](/business/nouns/account/sweep) (`verb:Account.sweep`) | `from` Account (an id), required: the `$id` of the first Account `Account.list` returns for `where: heldAt = payments`; `to` Account (an id), required: the `$id` of the first Account `Account.list` returns for `where: heldAt = cards`; `amount` money: example `{"amount":5000,"currency":"USD"}` | `account` Account, `transaction` Transaction |

Returns: the last call answers with `account`, `transaction` and its `action`, whose `status` is `done`, `pending` (waiting on an Approval or a Worker), `failed`, `canceled` or `refused`:

```json
{
  "api": "https://api.sb/leaseline.app",
  "account": {
    "$id": "https://api.sb/leaseline.app/accounts/account_1",
    "$type": "Account"
  },
  "transaction": {
    "$id": "https://api.sb/leaseline.app/transactions/transaction_1",
    "$type": "Transaction",
    "amount": {
      "amount": 5000,
      "currency": "USD"
    }
  },
  "action": {
    "$id": "https://api.sb/leaseline.app/actions/action_1",
    "operation": "Account.sweep",
    "status": "done"
  },
  "links": {
    "self": "https://api.sb/leaseline.app/actions/action_1"
  }
}
```

Next: offer “Do this every Monday”, or “Keep $10,000 in operating and sweep the rest to reserve”.

Calls: `Account.sweep`

Ask:

```text
Move $5,000 to the card balance.
Keep two weeks of card spend in the card balance.
Sweep everything over $20,000 to reserve every Friday.
```

API:

```bash
# Look up the Account: Account.list
FROM=$(curl "https://api.sb/leaseline.app/accounts?where=heldAt%20%3D%20payments&limit=1" \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" | jq -r '.accounts[0]["$id"] | split("/") | last')

# Look up the Account: Account.list
TO=$(curl "https://api.sb/leaseline.app/accounts?where=heldAt%20%3D%20cards&limit=1" \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" | jq -r '.accounts[0]["$id"] | split("/") | last')

# Account.sweep
curl -X POST https://api.sb/leaseline.app/accounts/$FROM/sweep \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"to":"'"$TO"'","amount":{"amount":5000,"currency":"USD"}}'
```

SDK:

```ts
import { $ } from 'startup-builder'

const [from] = await $.Account.list({ where: 'heldAt = payments', limit: 1 })
const [to] = await $.Account.list({ where: 'heldAt = cards', limit: 1 })
await $.Account.sweep({ from: from.$id, to: to.$id, amount: { amount: 5000, currency: 'USD' } })
```

CLI:

```bash
FROM=$(npx startup-builder do Account.list --json '{"where":"heldAt = payments","limit":1}' | jq -r '.accounts[0]["$id"] | split("/") | last')
TO=$(npx startup-builder do Account.list --json '{"where":"heldAt = cards","limit":1}' | jq -r '.accounts[0]["$id"] | split("/") | last')
npx startup-builder do Account.sweep --json '{"from":"'"$FROM"'","to":"'"$TO"'","amount":{"amount":5000,"currency":"USD"}}'
```

MCP:

```json
{
  "name": "do",
  "arguments": {
    "code": "const [from] = await $.Account.list({ where: 'heldAt = payments', limit: 1 })\nconst [to] = await $.Account.list({ where: 'heldAt = cards', limit: 1 })\nreturn await $.Account.sweep({ from: from.$id, to: to.$id, amount: { amount: 5000, currency: 'USD' } })"
  }
}
```

## Change it
- Do this every Monday.
- Keep $10,000 in operating and sweep the rest to reserve.

## Under the hood
- Systems: [Treasury](/systems/treasury), [Ledger](/systems/ledger)
- Nouns: [Account](/business/nouns/account), [Transaction](/business/nouns/transaction), [Entry](/business/nouns/entry)
- Events: [`Account.swept`](/business/events/Account.swept), [`Account.paidOut`](/business/events/Account.paidOut), [`Transaction.reconciled`](/business/events/Transaction.reconciled)
- Stripe objects: `Balance`, `Issuing Balance`, `Treasury FinancialAccount`, `Treasury OutboundTransfer`, `Payout`

Each place cash sits is an [Account](/business/nouns/account) of class `cash`: the payments balance, the card balance, operating, reserve and your bank. Revenue in the payments balance pays for nothing until it moves, so a Startup whose agents run ads keeps the card balance topped up.

[`Account.sweep`](/business/nouns/account/sweep) moves money between two Accounts you own, and never to your bank. From the payments balance to the card balance it lands at once; from a bank it takes up to five business days. A rule with `keep` holds a floor and moves the rest, such as $10,000 in operating and everything else to reserve.

[`Account.payout`](/business/nouns/account/payout) sends available cash to your bank. Payouts run daily by default; `instant` sends one within minutes for Stripe's instant payout cost, which posts as its own [Entry](/business/nouns/entry). A payout the bank returns lands back in the payments balance with a [Task](/business/nouns/task) to fix the bank details.