Building a receipt-scanning budget tracker with Amazon Bedrock, Lambda, and DynamoDB
--- The Problem I Kept Ignoring Every week, the same small annoyance played out: I'd snap a photo of a receipt, tell myself I'd log it later, and then completely forget. By the time I got around to reviewing my spending usually at the end of the month I'd already blown past a budget category without knowing it. Even when I did log expenses manually, I'd misclassify them, which quietly made my "budget tracking" useless. I didn't need another finance app with fifty features I'd never touch. I needed one thing done well: upload a receipt, get an instant answer on whether I'm still within budget. That's what I built. It's called BudgetSnap. What BudgetSnap Actually Does BudgetSnap is intentionally narrow in scope, and that's the point. The entire flow is: Upload a receipt image or PDF. Automatically extract the merchant, date, subtotal, tax, total, and category. Store the entry in a database. Compare the new spend against that category's budget limit. Return a clear, immediate status over budget or within budget with practical advice. No end-of-month surprises. No manual spreadsheet updates. Just upload and know. On the UI side, I kept things lightweight but functional: A responsive single-page interface that works on desktop and mobile. A budget period selector (week/month). A category override selector for when the AI gets it wrong. Editable budget limits per category. Real-time result cards showing spend status the moment a receipt is processed. How I Built It on AWS I built this incrementally so I always had something working, even as I layered in more capability. 1. Frontend — plain HTML, CSS, and JavaScript I skipped frameworks entirely to keep setup minimal and deployment fast. The frontend supports drag-and-drop uploads, a manual file picker, category budgeting controls, and a responsive layout. 2. AI extraction — Amazon Bedrock (Nova models) This is the core intelligence of the app. I enabled model access in Amazon Bedrock and used a Nova model to read the receipt content and return structured fields merchant, date, totals, category that the rest of the pipeline can store and evaluate. 3. Data layer — Amazon DynamoDB Two tables power the app: expenses — processed receipt entries. budgets — category limits. 4. Processing logic — a receipt processor AWS Lambda function It: Receives the upload context. Extracts receipt data (via the Bedrock path, or a fallback path more on that below). Looks up the relevant budget limit. Computes spend-before, spend-after, and any over-budget amount. Writes the final expense row to DynamoDB. Returns normalized JSON back to the UI. 5. API layer — an upload Lambda behind Amazon API Gateway It accepts multipart uploads from the browser, stores the file in Amazon S3, invokes the processor Lambda, and relays the processed result back to the frontend. 6. Event wiring — Amazon S3 triggers Tested end-to-end from upload through to the final budget status response. AWS Services Used Service Role Amazon S3 Stores uploaded receipt files and triggers processing AWS Lambda Runs the upload handler and the receipt processor Amazon API Gateway (HTTP API) Exposes the upload endpoint to the frontend Amazon DynamoDB Stores budgets and processed expense entries Amazon Bedrock (Nova models) Performs receipt understanding and categorization Amazon CloudWatch Logs Debugging and operational visibility across the pipeline Architecture Flow User uploads an image or PDF from the web app. API Gateway routes the request to the Upload Lambda. Upload Lambda writes the file to S3. The Processor Lambda runs using the S3 context. The processor checks budget data in DynamoDB. The processor writes the new expense entry to DynamoDB. The API returns budget status and advice back to the frontend all in one response payload. What I Learned A focused scope beats a broad scope. By solving one annoying, recurring task really well, I ended up with a fully deployed, genuinely useful app instead of a half-finished feature list. Technical takeaways Apply least-privilege IAM policies and validate permissions early across Lambda, S3, API Gateway, and DynamoDB, this saved me from several silent failures later. Amazon CloudWatch Logs is the backbone of debugging serverless workflows. Without it, tracing failures across a multi-Lambda pipeline would have been guesswork. Standardizing request/response schemas across frontend and backend made integration, testing, and iteration dramatically simpler. Keeping the architecture lightweight and modular made the app easy to deploy, maintain, and extend. Product takeaways Instant feedback is what users actually value in a budgeting tool not more data, faster answers. Over-budget nudges land better when they're short and practical, not verbose. Reducing user effort upload once, get an automatic budget check is what drives real adoption. Try It Yourself GitHub repo: github.com/limanindou/BudgetSnap Building BudgetSnap reminded me why serverless architectures are such a good fit for small, high-leverage tools like this: I could focus almost entirely on the problem — accurate extraction, meaningful budget feedback instead of managing infrastructure. That's exactly the kind of building I want to keep doing. If you've built something similar with Bedrock or a serverless receipt/document pipeline, I'd love to hear how you approached extraction and fallback handling drop a comment below!
This is a summary aggregated from Dev.to. Read the complete article on the original site:
Read full article at Dev.to