Interact with Plaid API for bank account verification. Check sandbox status, test Link tokens, inspect items and accounts, and debug bank verification issues. Uses sandbox environment for development.
Manage FuzzyCat's Plaid integration via curl. Currently in sandbox mode.
PLAID_CLIENT_ID=$(grep PLAID_CLIENT_ID .env.local | cut -d'"' -f2)
PLAID_SECRET=$(grep PLAID_SECRET .env.local | cut -d'"' -f2)
PLAID_ENV=$(grep PLAID_ENV .env.local | cut -d'"' -f2) # "sandbox"
# Base URL by environment
# sandbox: https://sandbox.plaid.com
# development: https://development.plaid.com
# production: https://production.plaid.com
PLAID_URL="https://${PLAID_ENV}.plaid.com"
# Check API status (no auth needed)
curl -s "https://status.plaid.com/api/v2/status.json" | python3 -m json.tool
# Create a Link token (for testing)
curl -s -X POST "$PLAID_URL/link/token/create" \
-H "Content-Type: application/json" \
-d "{
\"client_id\": \"$PLAID_CLIENT_ID\",
\"secret\": \"$PLAID_SECRET\",
\"user\": {\"client_user_id\": \"test-user-1\"},
\"client_name\": \"FuzzyCat\",
\"products\": [\"auth\"],
\"country_codes\": [\"US\"],
\"language\": \"en\"
}" | python3 -m json.tool
# Get item details (requires access_token from Link flow)
curl -s -X POST "$PLAID_URL/item/get" \
-H "Content-Type: application/json" \
-d "{
\"client_id\": \"$PLAID_CLIENT_ID\",
\"secret\": \"$PLAID_SECRET\",
\"access_token\": \"access-sandbox-xxx\"
}" | python3 -m json.tool
# Get auth data (account + routing numbers)
curl -s -X POST "$PLAID_URL/auth/get" \
-H "Content-Type: application/json" \
-d "{
\"client_id\": \"$PLAID_CLIENT_ID\",
\"secret\": \"$PLAID_SECRET\",
\"access_token\": \"access-sandbox-xxx\"
}" | python3 -m json.tool
# Get account balances
curl -s -X POST "$PLAID_URL/accounts/balance/get" \
-H "Content-Type: application/json" \
-d "{
\"client_id\": \"$PLAID_CLIENT_ID\",
\"secret\": \"$PLAID_SECRET\",
\"access_token\": \"access-sandbox-xxx\"
}" | python3 -m json.tool
# Create a sandbox public token (for testing without Link UI)
curl -s -X POST "$PLAID_URL/sandbox/public_token/create" \
-H "Content-Type: application/json" \
-d "{
\"client_id\": \"$PLAID_CLIENT_ID\",
\"secret\": \"$PLAID_SECRET\",
\"institution_id\": \"ins_109508\",
\"initial_products\": [\"auth\"]
}" | python3 -m json.tool
# Exchange public token for access token
curl -s -X POST "$PLAID_URL/item/public_token/exchange" \
-H "Content-Type: application/json" \
-d "{
\"client_id\": \"$PLAID_CLIENT_ID\",
\"secret\": \"$PLAID_SECRET\",
\"public_token\": \"public-sandbox-xxx\"
}" | python3 -m json.tool
# Fire a sandbox webhook
curl -s -X POST "$PLAID_URL/sandbox/item/fire_webhook" \
-H "Content-Type: application/json" \
-d "{
\"client_id\": \"$PLAID_CLIENT_ID\",
\"secret\": \"$PLAID_SECRET\",
\"access_token\": \"access-sandbox-xxx\",
\"webhook_code\": \"DEFAULT_UPDATE\"
}" | python3 -m json.tool
# Search institutions
curl -s -X POST "$PLAID_URL/institutions/search" \
-H "Content-Type: application/json" \
-d "{
\"client_id\": \"$PLAID_CLIENT_ID\",
\"secret\": \"$PLAID_SECRET\",
\"query\": \"Chase\",
\"products\": [\"auth\"],
\"country_codes\": [\"US\"]
}" | python3 -m json.tool
auth (account + routing numbers for ACH)user_good, password pass_goodserver/services/plaid.ts, app/api/plaid/ routes/api/plaid/webhook