Skip to main content

SnapTrade Transaction Capture Implementation

Overview

This document describes the implementation of transaction (activities) data capture from SnapTrade brokerage accounts. SnapTrade provides historical transaction data including buys, sells, dividends, deposits, withdrawals, fees, and more.

Key Concepts

Activities vs Orders

Activities (what we capture):
  • Updated once daily
  • May not have timestamps (only dates)
  • Only contain completed transactions that resulted in position changes
  • Often have years of history, sometimes entire account history
  • Cached data that’s refreshed daily
Orders (not currently captured):
  • Real-time order data
  • Includes pending and cancelled orders
  • More detailed timing information

Transaction Types

SnapTrade classifies transactions into common types: Most Common Types:
  • BUY - Asset bought (negative amount, positive units)
  • SELL - Asset sold (positive amount, negative units)
  • DIVIDEND - Dividend payout (positive amount)
  • CONTRIBUTION - Cash contribution/deposit (positive amount)
  • WITHDRAWAL - Cash withdrawal (negative amount)
  • REI - Dividend reinvestment
  • STOCK_DIVIDEND - Dividend paid in shares instead of cash
  • INTEREST - Interest deposited
  • FEE - Fee withdrawn (negative amount)
  • TAX - Tax-related fee
  • OPTIONEXPIRATION - Option expiration event
  • OPTIONASSIGNMENT - Option assignment event
  • OPTIONEXERCISE - Option exercise event
  • TRANSFER - Transfer between accounts
  • SPLIT - Stock split
Important Fields:
  • amount: Positive = gaining cash, Negative = spending cash
  • units: Positive = gaining shares, Negative = losing shares
  • Example: BUY has positive units and negative amount

Database Schema

Table: snaptrade_transactions

Indexes

  • idx_snaptrade_transactions_clerk_id
  • idx_snaptrade_transactions_account_id
  • idx_snaptrade_transactions_trade_date
  • idx_snaptrade_transactions_type
  • idx_snaptrade_transactions_symbol

API Endpoints

POST /api/snaptrade/fetch-activities

Fetches and stores transaction data for a specific account. Request Body:
Response:
Features:
  • Automatic pagination (fetches all pages)
  • Upsert logic to handle duplicates
  • Updates account sync status
  • Comprehensive error handling

Webhook Events

ACCOUNT_TRANSACTIONS_INITIAL_UPDATE

Triggered the first time SnapTrade collects transaction data from an account. Example Payload:

ACCOUNT_TRANSACTIONS_UPDATED

Triggered when account transactions are updated (daily refresh). Example Payload:

Webhook Handler Flow

When a transaction webhook is received:
  1. Validate webhook secret - Authenticate the request
  2. Fetch account details - Update balance and sync status
  3. Call fetch-activities endpoint - Retrieve all transactions
  4. Store activities - Upsert into snaptrade_transactions table
  5. Update account - Mark transactions_sync_completed = true
  6. Record webhook event - Log processing in snaptrade_webhook_events

Implementation Files

Created Files:

  1. /sql-queries/create-snaptrade-transactions-table.sql - Database schema
  2. /app/api/snaptrade/fetch-activities/route.ts - Activity fetching endpoint
  3. /docs/SNAPTRADE-TRANSACTIONS.md - This documentation

Modified Files:

  1. /app/api/snaptrade/webhook/route.ts:
    • Added handleTransactionsUpdate() function
    • Updated event handlers for transaction webhooks
    • Refactored legacy handleTradesSyncCompleted() to use new handler

Data Flow

Testing

To test the implementation:
  1. Create the database table:
  2. Trigger a webhook manually:
  3. Check the database:
  4. Verify webhook logging:

Performance Considerations

Pagination

  • SnapTrade API returns max 1000 transactions per page
  • Our implementation fetches all pages automatically
  • For accounts with 10+ years of history, expect multiple pages

Data Freshness

  • Transaction data is cached and refreshed once daily by SnapTrade
  • Not suitable for real-time transaction monitoring
  • Perfect for historical analysis and tax reporting

Upsert Strategy

  • Uses (snaptrade_account_id, snaptrade_activity_id) as unique key
  • Prevents duplicates while allowing updates to existing records
  • Safe to run multiple times without data duplication

Future Enhancements

  1. UI Integration
    • Display transaction history in frontend
    • Filter by type, date range, symbol
    • Export to CSV for tax purposes
  2. Analytics
    • Calculate cost basis
    • Track realized gains/losses
    • Generate tax reports
  3. Reconciliation
    • Compare SnapTrade transactions with holdings
    • Detect discrepancies
    • Alert on unusual activity
  4. Performance Optimization
    • Incremental updates (only fetch recent transactions)
    • Background job for initial sync of large histories
    • Caching frequently accessed data

Troubleshooting

Transactions not appearing

  1. Check webhook logs:
  2. Check account sync status:
  3. Check for errors in fetch-activities:
    • Look for 425 errors (sync not ready)
    • Verify user credentials are valid
    • Check SnapTrade API status

Duplicate transactions

  • Should not occur due to unique constraint
  • If duplicates appear, check snaptrade_activity_id values
  • Some brokers may not provide consistent activity IDs

Missing transaction data

  • SnapTrade data availability varies by broker
  • Some older transactions may not have complete data
  • Check raw_response field for actual data received

References