๐Ÿ’ฐ Budget Tracker

Gemini AI ยท Notion sync ยท Free forever

Receipt image
๐Ÿงพ

Click to upload or drag & drop โ€” multiple OK

or Ctrl+V
or paste text
Not synced yet
Period
to
Roll up grocery subcategories into "Groceries"
Categories
Spending breakdown
Monthly trend
AI insights
Select a period and click below.
Item lookup database

Maps Costco item numbers & receipt codes to full product names. Used automatically when parsing โ€” unknown items trigger a Gemini web search.

Item #Receipt nameFull product nameCategory
1 ยท Gemini API key (free โ€” handles receipt parsing)

Get a free key at aistudio.google.com/apikey โ€” sign in with Google โ†’ "Get API key" โ†’ copy it. Free tier: 1,500 requests/day, supports image upload.

2 ยท Cloudflare Worker proxy (free โ€” bridges browser โ†’ Notion)

Notion's API blocks direct browser requests (CORS). A free Cloudflare Worker acts as a middleman. Takes ~5 minutes:

  1. Go to workers.cloudflare.com โ†’ sign up free (no credit card) โ†’ "Create a Worker"
  2. Delete the default code and paste the code below โ†’ click "Deploy"
  3. Copy your worker URL (looks like your-worker.your-subdomain.workers.dev) and paste it below
export default { async fetch(request, env) { const ALLOWED = "YOUR_SITE_ORIGIN"; // e.g. "null" for local file, or your domain if (request.method === "OPTIONS") { return new Response(null, { headers: corsHeaders(ALLOWED) }); } const url = new URL(request.url); const target = url.searchParams.get("target"); if (!target || !target.startsWith("https://api.notion.com/")) { return new Response("Bad target", { status: 400 }); } const body = request.method !== "GET" ? await request.text() : undefined; const headers = {}; for (const [k, v] of request.headers.entries()) { if (k.toLowerCase() !== "host") headers[k] = v; } const resp = await fetch(target, { method: request.method, headers, body }); const respBody = await resp.text(); return new Response(respBody, { status: resp.status, headers: { ...corsHeaders(ALLOWED), "content-type": "application/json" } }); } }; function corsHeaders(origin) { return { "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Methods": "GET,POST,PATCH,DELETE,OPTIONS", "Access-Control-Allow-Headers": "Content-Type,Authorization,Notion-Version" }; }
3 ยท Notion integration (free โ€” stores your transactions)

Step A: Create an integration at notion.so/my-integrations โ†’ "New integration" โ†’ copy the Internal Integration Token.

Step B: In Notion, create a new full-page database. Open it โ€” the URL looks like:
notion.so/YOUR-DATABASE-ID?v=...
Copy the 32-character ID before the ?v=.

Step C: In the database, click ยทยทยท โ†’ "Add connections" โ†’ select your integration.

Step D: Click "Create Notion database" below โ€” this sets up the right columns automatically.

Data

"Push historical data" sends your two existing Costco trips (Jan 31 + Feb 13, 2026) to Notion.