name: ynab-api description: YNAB (You Need A Budget) comprehensive budget management with automated tracking, goal monitoring, spending analysis, and daily budget check reports. Ready-to-use scripts included. user-invocable: true metadata: {"clawdbot":{"emoji":"π°","requires":{"env":["YNAB_API_KEY","YNAB_BUDGET_ID"]}}}
YNAB Budget Management
Complete YNAB budget automation toolkit with best practices, automated monitoring, and ready-to-use helper scripts.
β¨ Features
- π Goal Progress Tracking - Monitor category goals with visual progress bars
- π Scheduled Transaction Alerts - Never miss upcoming bills
- π° Age of Money Monitoring - Track financial stability
- π Month-over-Month Analysis - Compare spending trends
- β οΈ Overspending Alerts - Get notified when exceeding budgets
- π Automated Daily Check - Morning budget summary via WhatsApp/Telegram
- π― Smart Categorization - Learn from transaction history
- πΈ Real Transfer Support - Properly linked account transfers
π Quick Start
This skill provides best practices for managing YNAB budgets via API, including transaction categorization, data consistency, and automated workflows.
π Installation & Setup
1. Get Your YNAB API Key
- Go to https://app.ynab.com/settings/developer
- Click "New Token" and copy your Personal Access Token
- Get your Budget ID from the YNAB URL (e.g.,
https://app.ynab.com/abc123...βabc123...)
2. Configure the Skill
Create config file at ~/.config/ynab/config.json:
{
"api_key": "YOUR_YNAB_TOKEN_HERE",
"budget_id": "YOUR_BUDGET_ID_HERE"
}
Or set environment variables:
export YNAB_API_KEY="your_token"
export YNAB_BUDGET_ID="your_budget_id"
3. Set Up Automated Reports (Recommended)
π ONE-COMMAND SETUP:
/home/node/clawd/skills/ynab-api/scripts/setup-automation.sh
This interactive script creates all recommended cron jobs:
- β Daily Budget Check (7:15 AM) - Age of Money, upcoming bills, alerts
- β Weekly Spending Review (Monday 8:00 AM) - Month comparison
- β Mid-Month Goal Check (15th, 9:00 AM) - Category goals progress
- β Upcoming Bills Alert (10:00 AM daily) - Next 2 days transactions
Preview changes first:
/home/node/clawd/skills/ynab-api/scripts/setup-automation.sh --dry-run
Manual setup (alternative):
If you prefer to create cron jobs manually:
openclaw cron add --name "Daily Budget Check" \
--schedule "15 7 * * *" \
--session isolated \
--model gemini-flash \
--delivery announce \
--task "Run YNAB daily budget check and send via WhatsApp"
4. Test Your Setup
Run a quick test:
/home/node/clawd/skills/ynab-api/scripts/goals-progress.sh
If you see your budget goals, you're all set! π
Core Best Practices
1. Always Categorize Immediately
Never create transactions without a category. Uncategorized transactions break budget tracking.
When adding a transaction, categorize it at creation timeβdon't defer.
2. Check Transaction History for Unknown Merchants
When you encounter an unfamiliar merchant/payee:
- Search YNAB for past transactions with the same payee name
- Use the same category as previous transactions
- Maintain consistency with historical categorization
Why: This preserves categorization consistency and reduces user interruptions.
Example:
# Search for past transactions by payee
curl -s "https://api.ynab.com/v1/budgets/$BUDGET_ID/transactions" \
-H "Authorization: Bearer $API_KEY" | \
jq '.data.transactions[] | select(.payee_name | contains("MERCHANT_NAME"))'
3. Check for Pending Transactions Before Adding
Before creating a new transaction:
- Check if an unapproved transaction already exists for the same amount
- If found β approve it and update payee/memo if needed
- If not found β create new transaction
Why: Avoids duplicates from imported bank transactions.
4. Use Milliunits for Amounts
YNAB API uses milliunits for all amounts:
- β¬10.00 =
10000(positive for income) - -β¬10.00 =
-10000(negative for expenses)
Always divide by 1000 when displaying, multiply by 1000 when submitting.
5. Monthly Expense Calculation
When calculating monthly spending:
- Only count transactions with
amount < 0(actual expenses) - Consider excluding non-discretionary categories like:
- Tax payments (mandatory, not spending choices)
- Advances/reimbursements (temporary, not true expenses)
- Uncategorized (often transfers/investments)
- Extraordinary one-time expenses (if tracking discretionary budget)
Note: Exclusion rules depend on your budget goals. Configure your specific exclusions in a local config or notes file.
6. Handle Split Transactions
Transactions with category "Split" contain subtransactions.
Never show "Split" as a category in reportsβalways expand to subcategories:
# For each split transaction
if [ "$category_name" = "Split" ]; then
for subtx in subtransactions; do
echo "$subtx.category_name: $subtx.amount"
done
fi
7. Transfer Transactions (CRITICAL)
β οΈ IMPORTANT: To create a real transfer that YNAB recognizes as linked transactions between accounts, you MUST use the account's transfer_payee_id, NOT a payee name.
How Transfers Work
Each account has a special field transfer_payee_id - this is the payee ID that represents transfers TO that account.
β CORRECT - Real Transfer:
# Transfer from Account A to Account B
# Get Account B's transfer_payee_id first, then:
curl -X POST "$YNAB_API/budgets/$BUDGET_ID/transactions" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d "{
\"transaction\": {
\"account_id\": \"ACCOUNT_A_ID\",
\"date\": \"2026-02-21\",
\"amount\": -50000,
\"payee_id\": \"ACCOUNT_B_TRANSFER_PAYEE_ID\",
\"approved\": true
}
}"
β WRONG - NOT a Real Transfer:
# Using payee_name creates a regular transaction, NOT a transfer
"payee_name": "Transfer: To Account B" # YNAB won't link this
Getting Transfer Payee IDs
Get all accounts with their transfer_payee_id:
curl "$YNAB_API/budgets/$BUDGET_ID/accounts" \
-H "Authorization: Bearer $API_KEY" | \
jq -r '.data.accounts[] | "\(.name): \(.transfer_payee_id)"'
Store these IDs in your personal config (TOOLS.md or local config file) for quick reference.
What Happens When Done Correctly
When you use transfer_payee_id:
- YNAB creates two linked transactions (one in each account)
- The matching transaction appears automatically in the destination account
- Both transactions are marked as transfers (not regular expenses/income)
- Category is automatically set to "Transfer" (no budget impact)
- Deleting one side deletes both
Common Transfer Mistakes
- Using payee_name β Creates regular transaction, not a transfer
- Manually creating both sides β Creates duplicates instead of linked pair
- Setting a category β Transfers shouldn't have categories (YNAB ignores it)
- Wrong transfer_payee_id β Transfer goes to wrong account
Transfer vs. Regular Transaction
| Transfer (payee_id = transfer_payee_id) | Regular Transaction (payee_name) |
|---|---|
| Two linked transactions created | Single transaction |
| Automatically categorized as Transfer | Needs category |
| No budget impact | Affects budget |
| Both sides auto-reconcile | Manual reconciliation |
Common Account IDs Structure
Store account IDs in config (example structure):
{
"accounts": {
"primary_checking": "UUID-HERE",
"savings": "UUID-HERE",
"cash": "UUID-HERE"
},
"default_account": "primary_checking"
}
Never hardcode account IDs in scriptsβuse config references.
Common Operations
Add Transaction
YNAB_API="https://api.ynab.com/v1"
curl -X POST "$YNAB_API/budgets/$BUDGET_ID/transactions" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d "{
\"transaction\": {
\"account_id\": \"$ACCOUNT_ID\",
\"date\": \"2026-02-21\",
\"amount\": -10000,
\"payee_name\": \"Coffee Shop\",
\"category_id\": \"$CATEGORY_ID\",
\"memo\": \"Morning coffee\",
\"approved\": true
}
}"
Create Transfer Between Accounts
# Step 1: Get destination account's transfer_payee_id
DEST_ACCOUNT_NAME="Savings"
TRANSFER_PAYEE_ID=$(curl -s "$YNAB_API/budgets/$BUDGET_ID/accounts" \
-H "Authorization: Bearer $API_KEY" | \
jq -r ".data.accounts[] | select(.name == \"$DEST_ACCOUNT_NAME\") | .transfer_payee_id")
# Step 2: Create transfer transaction
curl -X POST "$YNAB_API/budgets/$BUDGET_ID/transactions" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d "{
\"transaction\": {
\"account_id\": \"$SOURCE_ACCOUNT_ID\",
\"date\": \"2026-02-21\",
\"amount\": -50000,
\"payee_id\": \"$TRANSFER_PAYEE_ID\",
\"memo\": \"Monthly savings transfer\",
\"approved\": true
}
}"
# YNAB will automatically create the matching transaction in the destination account
Important: Only create ONE transaction - YNAB creates the matching side automatically.
Search Transactions
# Get transactions since date
curl "$YNAB_API/budgets/$BUDGET_ID/transactions?since_date=2026-02-01" \
-H "Authorization: Bearer $API_KEY"
# Filter by payee (client-side with jq)
... | jq '.data.transactions[] | select(.payee_name | contains("Coffee"))'
Get Categories
curl "$YNAB_API/budgets/$BUDGET_ID/categories" \
-H "Authorization: Bearer $API_KEY" | \
jq '.data.category_groups[].categories[] | {id, name}'
Monthly Spending Report
To calculate monthly spending:
- Get all transactions for the month
- Filter:
amount < 0(expenses only) - Exclude configured non-discretionary categories (taxes, transfers, etc.)
- Expand Split transactions into subcategories
- Sum by category or total
Tip: Consider separating small recurring expenses from large one-time purchases for better budget analysis.
π οΈ Available Scripts
All scripts are in /skills/ynab-api/scripts/ and ready to use.
setup-automation.sh [--dry-run]
β START HERE - One-command automation setup.
./setup-automation.sh # Interactive setup
./setup-automation.sh --dry-run # Preview changes
Creates all recommended cron jobs:
- Daily Budget Check (7:15 AM)
- Weekly Spending Review (Monday 8 AM)
- Mid-Month Goal Check (15th at 9 AM)
- Upcoming Bills Alert (10 AM daily)
What it does:
- Validates YNAB config exists
- Prompts for your WhatsApp number
- Creates 4 automation cron jobs
- Confirms successful setup
This is the recommended way to get started!
goals-progress.sh [month]
Shows visual progress bars for all category goals.
./goals-progress.sh # Current month
./goals-progress.sh 2026-01 # Specific month
Example output:
π PROGRESSI OBIETTIVI - 2026-02-01
Palestra ποΈβοΈ:
ββββββββββ 8% (β¬22/β¬270) π’
Salute βοΈ:
ββββββββββ 43% (β¬261/β¬500) π‘
Mangiare Fuori π:
ββββββββββ 119% (β¬178/β¬150) π΄
scheduled-upcoming.sh [days]
Lists upcoming scheduled transactions.
./scheduled-upcoming.sh # Next 7 days
./scheduled-upcoming.sh 30 # Next 30 days
Example output:
π
TRANSAZIONI PROGRAMMATE - Prossimi 7 giorni
2026-03-01 πΈ Lisa Valent: β¬-42.18 - Spotify
2026-03-02 πΈ Andrea Schiffo: β¬-84.36 - Spotify lui e moglie
---
TOTALE: β¬-126.54
month-comparison.sh [month1] [month2]
Compares spending between two months.
./month-comparison.sh # Current vs last month
./month-comparison.sh 2026-02 2026-01 # Specific months
Example output:
π CONFRONTO SPESE
2026-02-01 vs 2026-01-01
Casa π : β¬1,241 (era β¬450) β οΈ +176%
Mangiare Fuori π: β¬178 (era β¬120) βοΈ +48%
Palestra ποΈβοΈ: β¬100 (era β¬100) = 0%
---
TOTALE 2026-02: β¬5,298
TOTALE 2026-01: β¬3,450
Differenza: +β¬1,848 (+53.6%)
transfer.sh SOURCE_ACCOUNT DEST_ACCOUNT AMOUNT DATE [MEMO]
Creates a proper linked transfer between accounts.
./transfer.sh abc-123 "Savings" 100.50 2026-02-21 "Monthly savings"
Important: Uses transfer_payee_id for real transfers recognized by YNAB.
daily-budget-check.sh
Comprehensive morning budget report (designed for cron).
./daily-budget-check.sh
Example output:
βοΈ BUDGET CHECK MATTUTINO
π° Age of Money: 141 giorni β
π
Prossime uscite (7gg)
β’ Domani: Lisa Valent β¬42.18
β οΈ Alert Budget Superato
β’ Mangiare Fuori π: β¬178 / β¬150 (+β¬28)
π― Obiettivi in ritardo
β’ Palestra ποΈβοΈ: 8% (β¬22/β¬270)
This script is perfect for automated cron jobs to get daily budget insights.
Personal Configuration
For personal preferences (merchant mappings, category exclusions, default accounts):
Option 1: Add to your workspace TOOLS.md:
## YNAB Personal Config
- Default account: [account_id]
- Exclude from budget: Category1, Category2
- Merchant mappings: Store β Category
Option 2: Create local config file (e.g., ~/.config/ynab/rules.json):
{
"exclude_categories": ["Taxes", "Transfers"],
"merchant_map": {
"Coffee Shop": "category_id_here"
}
}
The skill will check transaction history for consistencyβyour personal preferences stay private.
Security Notes
- Never commit API keys to version control
- Store
YNAB_API_KEYin environment or secure config (~/.config/ynab/config.jsonwith 600 permissions) - Never log or display full API keys in output
API Documentation
Official YNAB API docs: https://api.ynab.com
Rate limit: ~200 requests per hour per IP.
π€ Automation Ideas
Daily Morning Check (Recommended)
Get a comprehensive budget overview every morning at 7:15 AM:
openclaw cron add --name "Daily Budget Check" \
--schedule "15 7 * * *" \
--session isolated \
--model gemini-flash \
--delivery announce \
--task "Run YNAB daily budget check and send via WhatsApp"
Weekly Spending Review
Every Monday morning, compare last week with previous week:
openclaw cron add --name "Weekly Spending Review" \
--schedule "0 8 * * 1" \
--session isolated \
--model gemini-flash \
--delivery announce \
--task "Compare current month vs last month YNAB spending"
Goal Progress Reminder
Mid-month reminder (15th) to check goal progress:
openclaw cron add --name "Mid-Month Goal Check" \
--schedule "0 9 15 * *" \
--session isolated \
--model gemini-flash \
--delivery announce \
--task "Show YNAB goals progress for current month"
Scheduled Transaction Alerts
Get notified 2 days before scheduled payments:
openclaw cron add --name "Upcoming Bills Alert" \
--schedule "0 10 * * *" \
--session isolated \
--model gemini-flash \
--delivery announce \
--task "Show YNAB scheduled transactions for next 2 days"
π‘ Pro Tips
- Set realistic goals: Use YNAB's goal feature for categories you want to track closely
- Review Age of Money: Target 30+ days minimum, 90+ is excellent
- Check scheduled transactions weekly: Avoid surprises from forgotten subscriptions
- Use import_id: When importing from CSV, use unique import_id to avoid duplicates
- Transfer payee IDs: Store these in your personal TOOLS.md for quick reference
- Categorize immediately: Never leave transactions uncategorized
- Monthly comparison: Use month-comparison.sh to spot spending trends
π Security Best Practices
- Store API key in config file with permissions
600 - Never commit
config.jsonto version control - Add to
.gitignore:config/ynab.json,.config/ynab/ - Rotate API tokens periodically (every 6-12 months)
- Use read-only tokens when possible (YNAB doesn't support this yet, but request it!)
π Troubleshooting
401 Unauthorized: API key invalid or expired
- Regenerate token at https://app.ynab.com/settings/developer
404 Not Found: Budget ID or transaction ID doesn't exist
- Verify budget ID in YNAB URL or with
/budgetsendpoint
429 Too Many Requests: Rate limit exceeded (~200 requests/hour)
- Add delays between bulk operations
- Cache frequently-used data (accounts, categories)
Transfer not linking: Using payee_name instead of transfer_payee_id
- See "Transfer Transactions (CRITICAL)" section above
Common mistakes:
- Forgetting milliunits (using 10 instead of 10000)
- Wrong date format (use YYYY-MM-DD)
- Missing required fields (account_id, date, amount)
- Using payee_name for transfers (use transfer_payee_id)
π Resources
- YNAB API Docs: https://api.ynab.com
- Budget templates: https://www.ynab.com/learn
- OpenAPI Spec: https://github.com/ynab/ynab-sdk-ruby/blob/main/open_api_spec.yaml
- Rate limits: ~200 requests/hour per IP
- Support: https://support.ynab.com
π What's Next?
After installation:
- β
Test with
goals-progress.sh - β Set up daily budget check cron
- β Store transfer_payee_ids in TOOLS.md
- β Configure personal category exclusions
- β Enjoy automated budget insights!
Happy budgeting! π°