Behind the product

How RECLAIM was built

This page covers the architecture, the decisions I made while building it, and what I'd do differently if I started over.

Kunal Kothari · Founder

The stack

LayerTechnologyWhy
FrontendNext.js 14 (App Router)Server components keep API keys server-side and reduce how much code ships to the browser. The file-based routing also meant less config to figure out.
Database & AuthSupabase (Postgres)The data is relational. Users have subscriptions, subscriptions have limits, audits belong to users. Postgres fits that structure well. Firebase's document store would've made those relationships harder to query. Supabase gave me Postgres plus auth plus row-level security without managing my own backend.
AIOpenAI GPT-4o (temp 0.2)GPT-4o follows complex instructions more reliably than the other models I tested. That matters when your prompt is enforcing a strict JSON schema and a detailed rule set. I run it at temperature 0.2 because I want consistent output. This isn't a creative writing tool.
PaymentsStripe (hosted checkout + webhooks)I don't touch card data at all, which keeps me out of PCI compliance scope. Stripe's hosted checkout handles the edge cases I'd otherwise get wrong.
HostingVercelVercel has native Next.js support and serverless functions that scale down to zero between requests. It also has built-in cron, which I use for scheduled jobs.
IntegrationGoogle Calendar OAuthCalendar data shows how time was actually spent, not how someone remembers it later. I request read-only access to event metadata only: titles, times, and attendee counts. I never read event descriptions or email content. That is the minimum scope needed for the analysis.

How a capacity audit works

01

Intake

The user goes through a five-screen guided form rather than typing into a blank text box. I made this change after early testing showed that the people who most needed the tool struggled to describe their own problems clearly enough for the AI to do anything useful. Business type determines which template they get.

02

Authentication

When the form submits, the request hits a Next.js API route that validates the user's session token through Supabase. Every query after that is scoped to that user's ID.

03

Rate limiting

Before calling the AI, the route queries the extractions table to count how many audits the user has run this calendar month. If they're at their plan limit, it returns a 429 and the frontend shows the upgrade prompt. The check runs server-side, so it can't be bypassed by the client.

04

Prompt assembly

The intake answers get converted into a structured context block and passed to the model. If Google Calendar is connected, 28 days of meeting data gets added at the top of that context. The system prompt specifies the rule set and the exact JSON structure the model has to return.

05

Generation

GPT-4o returns structured JSON. The parsing is wrapped in a try/catch block so a malformed response sends a clean error to the client instead of crashing the request.

06

Persistence

The result gets written to Supabase. That same table drives the audit history the user sees and the usage counter used for rate limiting. Using one table for both means the count always reflects what actually happened.

The hard part wasn't the API call

Connecting to OpenAI takes about twenty minutes. Getting it to produce output a small business owner will actually act on took several weeks and multiple rewrites.

The first version produced recommendations like “implement foot traffic analytics.” That's technically reasonable advice, but it's useless to someone running a small retail shop with no budget for new software.

So I built a constraint set into the system prompt. These rules are applied on every generation:

Constraint rules, applied on every generation

  • Never recommend purchasing additional software or analytics tools
  • Every recommendation must include a specific dollar figure, both monthly and annual
  • Every recommendation must include a literal first action completable in under ten minutes
  • For solo operators, never use the word "automate" or suggest delegating to a team member. They may not have one.
  • For physical businesses, never reference calendar blocking. Use physical cues instead, like a note on the register or a phone alarm.
  • Never say "consider" or "explore". Use DO, TEXT, CALL, CANCEL, BLOCK.
  • Reference the user's stated growth goals by name in the recommendations

What that changed

Before constraints

“Implement foot traffic analytics to better understand customer patterns and optimize staffing accordingly.”

After constraints

“Text each of your distributor reps today: Hey, moving all our calls to Wednesdays 10am-12pm. Works better for the store schedule. That conversation takes five minutes and reclaims about four hours every week, roughly $9,600 a year.”

Same model, same user input. The output changed because the constraints changed.

Decisions I made and why

Built a free calculator with no AI at all

Every AI audit costs real money to run. The calculator is pure arithmetic with zero marginal cost, so I can make it genuinely unlimited without requiring an account. It also means the core framework has value if an AI provider ever changes pricing or goes away.

Tradeoff

There are two codepaths to maintain. The calculator is also less accurate than the AI audit, but that gap is intentional. It's what gives people a reason to run the full audit.

Replaced the free-text input with a guided intake form

I tested the original blank text box with a small business owner and hit the problem quickly. The people who most need this kind of tool are often the least able to describe their own operational issues clearly. A blank box asked them to do the hard work before they'd gotten anything from the product.

Tradeoff

Five screens is more friction than one box. Output quality improved enough to justify it, and I kept a free-text option for users who already know what they want to say.

Google Calendar only for B2B business types

A liquor store owner doesn't run their week through Google Calendar. Showing a calendar connection prompt to a retail or trades user adds friction with no benefit. The integration appears only for business types where calendar data is actually useful. When it does connect, I request read-only access to event metadata: titles, times, and attendee counts. I don't read event descriptions or email content. That's the minimum scope needed for the analysis.

Tradeoff

B2C users get a less precise analysis because there's no calendar data to anchor it. The right fix is a different data source. Accounting software integration is next on the roadmap.

Removed the subscription tier, then brought it back

I launched with a monthly subscription, then removed it a few months later because there was nothing that justified a recurring charge. I brought it back once the weekly ops brief gave the subscription an actual ongoing value. Charging monthly for something a user has to actively remember to open is asking for churn.

Tradeoff

Pricing changed publicly more than once, which is not ideal. But the alternative was keeping a subscription that wouldn't have retained anyone.

Usage limits enforced against the database, not client state

The audit counter reads directly from the extractions table, filtered to the current month. There's no separate counter that could get out of sync. The source of truth is the actual audit records, so there's nothing to game.

Tradeoff

It adds one extra query on every dashboard load. That's a small cost for a limit that actually works.

What I'd do differently

First, I'd test the output with a real user before building the interface around it. I spent time on a polished dashboard before the underlying output was actually useful. The product got much better the day someone told me the recommendations were worthless. That conversation could've happened weeks earlier.

Second, I'd add analytics before launch rather than after. I have no data on where users dropped off in the first version, which makes it hard to know what to prioritize.

Third, I'd pick a customer segment and commit to it. I switched between targeting BizOps leaders and small business owners more than once. Each switch meant rewriting the positioning and, in some cases, parts of the product logic. I'm confident the segment I'm on now is correct. It just took longer to get there than it needed to.

I should also mention that all of this was built without a computer science background. I learned the relevant concepts by needing to make these specific decisions, not by studying them first. That's a slower way to learn, but it means I understand why each piece is there.

What's next and why

1

Automated weekly brief

This is the next thing I'm building. A report that arrives on its own is a different kind of product from a tool someone has to remember to open. That difference is what makes a monthly subscription worth paying for.

2

Accounting integration (QuickBooks/Xero)

Calendar data only tells me about businesses where meetings are the primary time sink. Revenue and payroll data would let me calculate the actual dollar cost of overhead instead of estimating it, and it applies to every business type.

3

Industry templates beyond the current five

Five templates are live: retail, food service, trades, consulting, and agencies. Each one I add improves the specificity of the output for that business type in a measurable way. I'm picking the next ones based on what's actually coming through the intake form.

Questions about any of this?

If you want to talk through the decisions, reach out.