Sign in
Enter your credentials to continue
Don't have an account? Create one
⚙ Settings
→ Sign out
CostCode
v4.1
Org: YOUR COMPANY
0 Unassigned
$0 Month to date
 Auto-coded
GC
Total Spend
$0.00
Import a statement to begin
$
Transactions
0
Auto-Code Rate
After first import
🎯
Needs Attention
0
Unassigned · 0 missing receipts
Spend by category No data
Spend by job MTD
Recent transactions
DateMerchantCard JobCost CodeCategory AmountReceipt
Processing: file.csv Parsing
Detecting bank format and parsing columns
Matching vendor rule library (40+ rules)
Applying keyword coding for unrecognized vendors
Checking for duplicates and writing to ledger
Drop a bank statement CSV or click to browse
Transactions will be parsed, auto-coded, and loaded into the ledger
Chase Amex Bank of America Capital One US Bank Wells Fargo Generic CSV
Supported statement formats
🏦 Chase Business
Transaction Date, Post Date, Description, Category, Type, Amount
💳 Amex Business
Date, Description, Amount, Extended Details
🏛️ Bank of America
Posted Date, Reference Number, Payee, Address, Amount
🔴 Capital One
Transaction Date, Posted Date, Card No., Description, Debit, Credit
🏦 US Bank
Date, Transaction, Name, Memo, Amount
📄 Generic CSV
Any CSV with date, description, amount — auto-detects columns
Current period open
All transactions are editable
0 selected
0 / 0
Date Merchant Card · Holder Job Cost Code Category Amount Conf. ReceiptNoteFlags
Card → Default Job Charges auto-assign to this job by default
Job → Active Cost Codes Click a job to manage its cost codes
Vendor overrides for:
These rules override global vendor rules for this job only. Higher confidence than global rules.
Select a job above to see its vendor overrides
Jobs
CodeNameSpendBudgetStatus
Cost Codes
CodeDescriptionCategoryScopeSpend
0 rules
Spend by job
Category mix
Job summary
JobNameMaterialsFuelEquipPartsOtherTotalBudget
📅 Monthly snapshots Click "View in ledger" to filter transactions by month
🏢 Company
🤖 AI configuration
🔔 Budget alerts
🗄️ Supabase
📤 Export
💬 SMS alerts
👥 Team access
Company profile
Applied to all exported reports and PDFs
AI configuration
Controls how unrecognized vendors are coded on import
Transactions below this threshold go to manual review
Budget alerts
Get notified when job spending approaches or exceeds budget. Alerts appear as banners in the ledger.
Enable budget alerts
Off by default — turn on to monitor job budgets
Supabase
Connect your Supabase project to persist data across sessions
Go to Project Settings → API, then copy the Project URL and anon public key below.
Database schema — paste into Supabase SQL Editor and run
-- Run all at once in Supabase SQL Editor

CREATE TABLE IF NOT EXISTS jobs (
  id uuid DEFAULT gen_random_uuid() PRIMARY KEY,
  user_id uuid REFERENCES auth.users DEFAULT auth.uid(),
  code text NOT NULL, name text, type text, location text,
  budget numeric, status text DEFAULT 'Active', cost_codes text[],
  created_at timestamptz DEFAULT now(),
  UNIQUE(user_id, code));

CREATE TABLE IF NOT EXISTS cards (
  id uuid DEFAULT gen_random_uuid() PRIMARY KEY,
  user_id uuid REFERENCES auth.users DEFAULT auth.uid(),
  last4 text, bank text, holder text, default_job text, purpose text,
  UNIQUE(user_id, last4));

CREATE TABLE IF NOT EXISTS transactions (
  id uuid DEFAULT gen_random_uuid() PRIMARY KEY,
  user_id uuid REFERENCES auth.users DEFAULT auth.uid(),
  date date, merchant text, amount numeric,
  card_last4 text, job_code text, cost_code text,
  category text, confidence integer, status text DEFAULT 'pending',
  has_receipt boolean DEFAULT false, receipt_url text,
  note text, anomalies text[], source_file text,
  imported_at timestamptz DEFAULT now());

CREATE TABLE IF NOT EXISTS statements (
  id uuid DEFAULT gen_random_uuid() PRIMARY KEY,
  user_id uuid REFERENCES auth.users DEFAULT auth.uid(),
  filename text, bank text, tx_count integer, total_amount numeric,
  imported_at timestamptz DEFAULT now());

CREATE TABLE IF NOT EXISTS audit_log (
  id uuid DEFAULT gen_random_uuid() PRIMARY KEY,
  user_id uuid REFERENCES auth.users DEFAULT auth.uid(),
  user_email text, action text, entity text, entity_id text,
  old_val text, new_val text, created_at timestamptz DEFAULT now());

CREATE TABLE IF NOT EXISTS profiles (
  id uuid DEFAULT gen_random_uuid() PRIMARY KEY,
  user_id uuid REFERENCES auth.users DEFAULT auth.uid() UNIQUE,
  company text, license_id text, phone text, email text,
  created_at timestamptz DEFAULT now());

-- Enable Row Level Security
ALTER TABLE jobs ENABLE ROW LEVEL SECURITY;
ALTER TABLE cards ENABLE ROW LEVEL SECURITY;
ALTER TABLE transactions ENABLE ROW LEVEL SECURITY;
ALTER TABLE statements ENABLE ROW LEVEL SECURITY;
ALTER TABLE audit_log ENABLE ROW LEVEL SECURITY;
ALTER TABLE profiles ENABLE ROW LEVEL SECURITY;

-- Policies (drop first to allow re-running)
DROP POLICY IF EXISTS "own data" ON jobs; DROP POLICY IF EXISTS "own data" ON cards;
DROP POLICY IF EXISTS "own data" ON transactions; DROP POLICY IF EXISTS "own data" ON statements;
DROP POLICY IF EXISTS "own data" ON audit_log; DROP POLICY IF EXISTS "own data" ON profiles;

CREATE POLICY "own data" ON jobs FOR ALL USING (auth.uid() = user_id);
CREATE POLICY "own data" ON cards FOR ALL USING (auth.uid() = user_id);
CREATE POLICY "own data" ON transactions FOR ALL USING (auth.uid() = user_id);
CREATE POLICY "own data" ON statements FOR ALL USING (auth.uid() = user_id);
CREATE POLICY "own data" ON audit_log FOR ALL USING (auth.uid() = user_id);
CREATE POLICY "own data" ON profiles FOR ALL USING (auth.uid() = user_id);

-- Receipts storage bucket (run once separately if needed)
INSERT INTO storage.buckets (id, name, public) VALUES ('receipts','receipts',false) ON CONFLICT DO NOTHING;
Export
Configure report format and delivery preferences
Include company logo on exported PDFs
Include unassigned transactions in export
SMS alerts
Twilio integration — approximately $1.50/month at current volume
Enable SMS alerts
$1.15/month + $0.01/message · Twilio
Team access
Invite team members and manage their access level. Viewers can see all transactions and add notes. Owners can import, edit, and export.
Team invitations require Supabase to be configured. Set up Supabase first in the Supabase tab.
Viewer: read + notes. Owner: full access including import and export.
Current team
Connect Supabase to manage team members
Saved