Build a Serverless Receipt Processing Pipeline with AWS Textract, Lambda, DynamoDB, and SES
Receipt processing is a common business workflow that often begins with manual data entry. A serverless AWS pipeline can automate that process: a receipt is uploaded to Amazon S3, its contents are extracted with Amazon Textract, the structured result is saved to DynamoDB, and a summary is sent through Amazon SES.
This project demonstrates how managed AWS services can work together to create a scalable workflow without provisioning or maintaining servers. It is also a practical portfolio project because it combines event-driven architecture, machine learning-powered document extraction, NoSQL storage, and email automation.
Architecture Overview
The pipeline follows a simple event-driven flow:
- A receipt image or PDF is uploaded to an Amazon S3 bucket.
- The S3 upload event invokes the receipt processor Lambda function.
- Lambda calls the Amazon Textract
AnalyzeExpenseAPI. - The extracted receipt data is written to an Amazon DynamoDB table.
- Lambda sends a receipt summary to a verified email address using Amazon SES.
AWS Services Used
- Amazon S3: Stores uploaded receipt files and emits object-created events.
- AWS Lambda: Runs the processing logic in response to an S3 event.
- Amazon Textract: Uses the
AnalyzeExpenseAPI to identify receipt fields and line items. - Amazon DynamoDB: Stores the extracted receipt data in a queryable format.
- Amazon SES: Sends an email notification containing the processing result.
- Amazon CloudWatch: Provides logs for troubleshooting and operational visibility.
Prerequisites
Before deploying the workflow, prepare:
- An AWS account with permission to create the required resources
- The AWS CLI installed and configured
- Python 3.x and Boto3 for local development or code review
- A verified sender and recipient identity in Amazon SES
1. Create the Storage and Database Resources
Create an S3 bucket for receipt uploads and a DynamoDB table named Receipts. Configure receipt_id as the table's primary key so every processed receipt can be stored and retrieved individually.
The S3 bucket is the entry point for the workflow. When a new receipt is uploaded, an object-created notification will invoke the Lambda function. Keep the source bucket and notification configuration focused so the function does not process unrelated objects.
2. Configure the Lambda Function
Deploy the receipt processor code in Reciptproccessor.py using a Python 3.x runtime. The function should read the bucket name and object key from the S3 event, call Textract, transform the response, write the result to DynamoDB, and send the notification through SES.
Receipt analysis can take longer than a trivial Lambda invocation, so configure a timeout in the range of 30 to 60 seconds and review the memory setting after testing with representative files.
3. Grant Least-Privilege Permissions
The Lambda execution role needs permission to perform the operations required by the workflow:
s3:GetObjectfor receipt files in the source buckettextract:AnalyzeExpensefor document analysisdynamodb:PutItemfor the target tableses:SendEmailfor the verified SES identity- CloudWatch Logs permissions for operational debugging
Scope each permission to the specific bucket, table, SES identity, and region where possible. Avoid using broad administrator permissions for the Lambda function in a production deployment.
4. Configure Environment Variables
Store deployment-specific values in Lambda environment variables instead of hard-coding them in the source code:
DYNAMODB_TABLE: the DynamoDB table name, such asReceiptsSES_SENDER_EMAIL: a verified sender addressSES_RECIPIENT_EMAIL: the address that receives summaries
5. Connect S3 to Lambda
Configure an S3 Event Notification for PUT object events and select the receipt processor Lambda function as the destination. Uploading a supported JPG, PNG, or PDF receipt should now start the pipeline automatically.
6. Test the Workflow
Upload a sample receipt with the AWS CLI:
aws s3 cp my-receipt.jpg s3://your-bucket-name/
After the upload, verify each stage of the workflow:
- Open CloudWatch Logs and confirm that Lambda received the S3 event.
- Check that Textract returned the expected vendor, date, total, and items.
- Open DynamoDB and confirm that a new receipt item was written.
- Check the recipient inbox for the SES receipt summary.
Troubleshooting Common Failures
- No Lambda invocation: review the S3 event notification and Lambda invoke permission.
- Access denied: inspect the Lambda role and confirm each resource ARN and AWS region.
- No email: verify both SES identities and check whether the account is still in the SES sandbox.
- Unexpected extraction: test with a clear, supported receipt image and inspect the raw Textract response in CloudWatch.
- Timeouts: increase the Lambda timeout and memory allocation after measuring the function's execution time.
Future Improvements
The initial workflow can be extended into a more complete receipt management application:
- Add a web interface for authenticated receipt uploads.
- Classify expenses such as food, travel, or office supplies.
- Add status fields such as Pending, Processed, and Rejected.
- Use Amazon SNS or a dead-letter queue for failure notifications.
- Generate monthly expense reports from DynamoDB data.
- Use Amazon Cognito to control who can upload and view receipts.
Final Thoughts
This project shows how a small collection of managed AWS services can turn an unstructured document into useful business data. It is a strong hands-on exercise for learning event-driven design, IAM permissions, serverless Python, and practical cloud troubleshooting.
You can explore the complete source code and architecture diagram in the Automated AWS Receipt Processing System GitHub repository.