Split shared rental utility bills with gpt-5.6-terra Vision, Postgres and Gmail

Go to Workflow
0 views
Built by Khairul Muhtadin Khairul Muhtadin
Created on September 03, 2026

Description

Split the utility bill fairly without spreadsheet drama. Snap a photo of the bill and this workflow reads it with AI vision, splits charges across rental units by occupancy weight, and notifies owners and tenants. A daily sweep catches anything left unpaid.

Last updated: September 2026.

Quick Overview
This workflow accepts forwarded utility bill images via a webhook, uses OpenAI gpt-5.6-terra Vision to extract bill details, splits the total across rental units using Postgres tenant weights, and then notifies owners and tenants via Gmail and Discord, with daily follow-ups for any bills not completed.

How it works
Receives a POST webhook request containing a utility bill image (URL or base64) and basic metadata from an email forward or form.
If an image is present, sends it to OpenAI gpt-5.6-terra Vision and parses the returned JSON fields such as provider, dates, period, and total amount.
Rejects unreadable bills, missing totals, or non-positive totals by logging them to Postgres and alerting the team via Discord and Gmail.
For valid bills, loads the tenant roster from Postgres and calculates a deterministic per-unit charge split proportional to each unit’s occupancy weight with cent-accurate rounding.
Stores the bill and per-unit charge records in Postgres, posts a split summary to Discord, emails the owner a detailed breakdown, and emails each tenant their individual charge.
Marks the bill as done in Postgres after tenant notifications are sent.
Runs daily on a schedule to find older bills not marked done in Postgres and posts/email a follow-up list (or an all-clear) to Discord and the owner.

Setup
Add credentials for OpenAI (API key), Postgres, Gmail OAuth2, and a Discord bot, and ensure the Discord server/channel IDs match your workspace.
Create the Postgres tables used by the workflow (ub_tenants, ub_bills, and ub_meter_readings) and ensure ub_bills has a unique constraint on bill_id.
Populate ub_tenants with each unit’s tenant name, email, and occupancy_weight values used to split bills.
Update the owner notification email address in the Gmail steps and confirm tenant emails in ub_tenants are correct.
Copy the webhook URL for the “utilitybill” endpoint and configure your email forwarding rule or intake form to POST the image_url or image_base64 fields to it.
Adjust the daily sweep cron expression (default 08:00) and workflow timezone if needed.

Quick Answers
How is the split calculated?
Proportionally by each unit's occupancy weight, with cent-accurate rounding.
What if a bill can't be read?
It gets logged to Postgres and the team is alerted via Discord and Gmail.
Which tables do I need?
ub_tenants, ub_bills, and ub_meter_readings in Postgres.

Additional info
Built with n8n. Need an assessment on your business? Feel free to reach out at https://khmuhtadin.com/consultation/

Nodes Used (5)

Code
n8n-nodes-base.code
Discord
n8n-nodes-base.discord
Gmail
n8n-nodes-base.gmail
HTTP Request
n8n-nodes-base.httpRequest
Postgres
n8n-nodes-base.postgres