Skip to main content

Sync Venmo Balance and Transactions to Lunch Money

This is a small tool for automatically cashing out your Venmo balance so that each individual payment you receive has an associated bank transfer. It also syncs Venmo transaction notes and payees back to Lunch Money.

I built this because I wanted a cleaner way to track Venmo reimbursements. Typically, an incoming Venmo is for a shared expense I've already covered. By syncing the Venmo metadata back to Lunch Money, I can accurately categorize my "true spend" without a mess of unlinked transactions.

Installation

This project uses uv for dependency management.

git clone https://github.com/iloveitaly/lunchmoney-venmo-track
cd lunchmoney-venmo-track
cp .env-example .env
uv sync

Usage

$ lunchmoney-venmo-track --token=XXX --allow-remaining
Your balance is $50
There are 3 transactions to cash-out

 -> Income: +$15.00 -- Mako (Dia beacon museum tickets)
 -> Income: +$15.00 -- David (Dia beacon museum tickets)
 -> Income: +$20.00 -- Randolf (Dinner)

All Venmo transactions processed successfully!

Features

  • Automatic Cashout: Triggers bank transfers for your Venmo balance based on individual received payments.
  • Lunch Money Sync: Matches Venmo transactions to Lunch Money entries by amount and updates them with notes and payee names.
  • Consistent Tracking: Only cashes out amounts that match recent transactions to ensure everything is accounted for.
  • Cron Ready: Includes built-in support for healthcheck heartbeats and internet connection retries for reliable scheduled execution.
  • Structured Logging: Uses structlog for clean, searchable logs in both console and JSON formats.
  • Docker Support: Pre-built container image with built-in cron daemon for automated scheduling.

Bank Transfers and Unofficial API

This tool relies on an unofficial, reverse-engineered Venmo API. When executed without --dry-run or --skip-transfer, it initiates real bank transfers to cash out your Venmo balance to your linked bank account.

  • Use --dry-run to test transaction discovery and matching without initiating bank transfers or writing to the database.
  • Use --skip-transfer to record transactions and sync metadata to Lunch Money without triggering bank transfers.

Consistent Tracking

By default, the tool only cashes out amounts that add up to the most recent transactions. This is useful when the script is running on a cron-job and you want to be sure it never misses an individual payment cash out (This can happen when the tool runs immediately after a payment is received, but before the payment appears in the transaction list).

If you wish to cash-out everything, use the --allow-remaining option. Otherwise, the tool will exit when there is a remainder.

$ lunchmoney-venmo-track --token=XXX --allow-remaining
Your balance is $39.95
There are 3 transactions to cash-out

 -> Income: +$15.00 -- Mako (Dia beacon museum tickets)
 -> Income: $24.95 of extra balance

All Venmo transactions processed successfully!

Lunch Money Integration

The script looks for transactions in Lunch Money which are part of an arbitrary Venmo category; these transactions are matched against previously tracked Venmo transactions by matching the exact amount.

The Lunch Money transaction is then updated with the Payee and Note from the Venmo transaction.

$ lunchmoney-venmo-track --token=XXX --lunchmoney-token=XXX --lunchmoney-category=z-venmo
Your balance is $0.00
There are 0 income transactions to cash-out
There are 1 expense transactions to track

 -> Expense: -$28.29 -- Randolf Tjandra (Volcano curry)

Lunch Money Updates: 1 / 1 transactions matched

 -> Randolf Tjandra (Volcano curry) → LM: 242330937

All Venmo transactions processed successfully!

Getting your API token

Venmo actively blocks automated OAuth logins with random device IDs (Error 240: OAuth2 Exception). You have two ways to get your token:

  1. Open DevTools in your browser (Network tab).
  2. Log into account.venmo.com.
  3. Filter requests by auth and inspect the https://account.venmo.com/api/auth request.
  4. Copy the access_token from the response JSON (or from the Authorization: Bearer <token> request header of any authenticated call).
  5. Set VENMO_API_TOKEN to this value.

Option 2: Use CLI with browser device ID

If you prefer to generate a token through the CLI, pass the v_id cookie from a browser that is already signed in to Venmo. A random device id is what triggers error 240.

v_id is HttpOnly, so the page console cannot read it. document.cookie does not include it. Copy it from DevTools:

  1. Open account.venmo.com in the browser you already use for Venmo.
  2. Open DevTools → Application (Chrome) or Storage (Firefox) → Cookies.
  3. Select https://account.venmo.com. Check https://venmo.com if the cookie is listed there instead.
  4. Copy the v_id value. It looks like fp01-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.

The same value is on the Network tab. Reload the page, open a request to venmo.com, and read v_id from the Cookie request header. Authenticated API calls also send it as device-id or x-device-id.

lunchmoney-venmo-track get-access-token --device-id "fp01-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

Stay in the browser profile where you are already signed in. A new profile receives a new v_id, and Venmo treats that as an unknown device.

Docker

A pre-built multi-arch image is published to GitHub Container Registry:

docker run -d \
  --name lunchmoney-venmo-track \
  --env-file .env \
  -v $(pwd)/transactions.db:/app/transactions.db \
  ghcr.io/iloveitaly/lunchmoney-venmo-track:latest

The container automatically schedules execution with the SCHEDULE cron expression (defaults to 0 6 * * *, daily at 6:00 AM).

To manually run the sync command that cron executes and verify everything is working:

docker exec -it <cid> lunchmoney-venmo-track

Heartbeat Support

You can specify a HEARTBEAT_URL environment variable to be pinged after each successful execution. This is highly recommended for monitoring your cron jobs. We recommend using Uptime Kuma to monitor these heartbeats.

Environment Variables

You can configure the tool using a .env file or environment variables instead of CLI flags:

# Required
export VENMO_API_TOKEN=""

# Optional - Lunch Money Integration
export TRANSACTION_DB="transactions.db"
export LUNCHMONEY_TOKEN=""
export LUNCHMONEY_CATEGORY=""

# Optional - Behavior & Monitoring
export ALLOW_REMAINING="true"
export HEARTBEAT_URL=""
export JSON_LOGGING="false"
export LOG_LEVEL="INFO"

# Optional - Docker / Cron Schedule
export SCHEDULE="0 6 * * *"

Credits

Originally forked from evanpurkhiser/venmo-auto-cashout.

MIT License

Metadata

Release files for lunchmoney-venmo-track 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for lunchmoney-venmo-track 0.3.0
File Size Uploaded
lunchmoney_venmo_track-0.3.0.tar.gz 10.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for lunchmoney-venmo-track 0.3.0
File Interpreter ABI Platform
lunchmoney_venmo_track-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 23.9 kB

Release files / lunchmoney_venmo_track-0.3.0.tar.gz

Download URL lunchmoney_venmo_track-0.3.0.tar.gz
Size 10.7 kB
Tags Source
SHA-256 checksum
How to use checksums
00f220757f49f3457e84d07be7cfa6d133a45c59b41701658cff91a745b26cba
BLAKE2b-256 checksum
How to use checksums
68931bc16549d92d2ea3a5bcb34a72092dcdfd9252ff43634e618a77aff40d4b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.10 {"installer":{"name":"uv","version":"0.12.10","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / lunchmoney_venmo_track-0.3.0-py3-none-any.whl

Download URL lunchmoney_venmo_track-0.3.0-py3-none-any.whl
Size 13.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
81dbe297327ed557fedd4386b98e58774656b76e8fa17eae7474bb338cdd8ae2
BLAKE2b-256 checksum
How to use checksums
58f9b7f31e2d4faebdfb6b9661d05e9ff5c98cc7a1513965a17c00bb9cea7d9b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.10 {"installer":{"name":"uv","version":"0.12.10","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 release files

0.2.0

2 release files

0.1.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page