Inspiration

It started with a $50 charge on a Tuesday morning.

I had signed up for a course trial three weeks earlier, told myself I'd cancel before the billing date, and then like most people completely forgot. The money wasn't the point. The frustration was. Not at the company, but at myself, and at the fact that this is a solved problem that nobody has actually solved.

The math is quietly staggering. Studies estimate that the average consumer wastes over $273 per year on subscriptions they no longer use, many of which started as free trials. That's not a spending problem. That's an attention problem. And attention problems are exactly what autonomous AI agents are built to fix.

ZeroCharge was born from a simple question: what if your inbox could protect you automatically, the moment a trial confirmation arrives?


How We Built It

ZeroCharge is a full-stack agentic pipeline with three distinct layers, each powered by a different Amazon Nova capability.

1. Email Parsing — Amazon Nova 2 Lite

When a trial confirmation email is pasted into the dashboard, we dispatch it to Amazon Nova 2 Lite via Amazon Bedrock's Converse API. The model is prompted to act as a structured data extractor, returning a strict JSON object:

{
  "vendor_name": "DummyStream",
  "monthly_cost": 14.99,
  "cancellation_url": "file:///path/to/billing.html",
  "trial_end_date": "7 days"
}

We chose Nova 2 Lite for this task deliberately. It is fast, cost-efficient, and handles the unstructured, varied language of marketing emails with high fidelity at temperature: 0.0.

The backend computes the cancellation window using the formula:

$$d_{\text{cancel}} = \max\left(0,\ d_{\text{trial}} - 1\right)$$

This ensures the cancellation is triggered one day before the charge clears, giving a safety buffer against timezone drift and billing system latency.

2. Autonomous Browser Agent — Amazon Nova Act

When the cancellation is due, ZeroCharge doesn’t send a reminder or wait for you to act. It automatically opens the browser and completes the cancellation for you.

Amazon Nova Act receives the cancellation URL and a natural-language instruction:

"Find the cancel subscription button using data-testid="initiate-cancel-btn" and click it. A modal will appear. Inside the modal, find the confirmation button and click it."

Nova Act interprets the live DOM, reasons about the UI state at each step, and navigates the cancellation flow entirely autonomously — no selectors to maintain, no scripts to break when the UI updates. It is genuinely general-purpose browser intelligence.

3. Async Orchestration — FastAPI

The backend is built on FastAPI with a carefully designed async architecture:

  • POST /api/parse-email — runs Nova 2 Lite in asyncio.to_thread() to keep the event loop unblocked
  • POST /api/exhume — awaits run_exhumation_agent() directly, holding the HTTP connection open for the ~20 second browser session
  • The frontend owns all orchestration logic, no fire-and-forget background tasks that lose the response

This architecture means the success signal propagates all the way from Nova Act's browser session → FastAPI response → React state update → UI flip to green.

Email Text
    │
    ▼
Nova 2 Lite (Bedrock)
    │  structured JSON + days_until_cancellation
    ▼
Frontend checks d_cancel == 0
    │
    ▼
POST /api/exhume  ──── awaits ~20s ────▶  Nova Act Agent
                                               │  clicks cancel
                                               │  clicks confirm
                                               ▼
                                        {"status": "success"}
                                               │
                                               ▼
                                        UI flips green 
                                        $totalMoneySaved += cost

What We Learned

1. Agentic reliability requires explicit state tracking. Nova Act occasionally throws Playwright teardown exceptions after a successful action. The browser closes mid-event-loop. We learned to track action_completed = True before the context manager exits, so teardown noise is silenced while real failures still surface.

2. HTTP semantics and business logic must be decoupled. Early versions checked response.ok to determine success. But a Playwright teardown crash can cause FastAPI to return a 500 even when the cancellation fully succeeded. The fix was to always parse the response body and check data.status === "success", making the UI resilient to transport-layer noise.

3. Background tasks are the wrong primitive for user-facing flows. FastAPI.BackgroundTasks fires and forgets the response returns immediately with no outcome. For a UI that needs to reflect a real-world action (a subscription being cancelled), the route must stay open and await the result. This is a subtle but critical architectural distinction.

4. Nova 2 Lite handles linguistic variance better than regex ever could. Trial emails say things like "your trial ends in 7 days", "you'll be charged on March 23rd", "enjoy 14 days on us". A single LLM prompt handles all of these with zero brittle pattern matching.


Challenges

Async boundary between Nova Act and FastAPI. Nova Act's Playwright session is synchronous and must run in a thread pool via asyncio.to_thread. Getting the error handling right across this boundary, especially distinguishing genuine failures from teardown crashes took significant iteration.

Relative date parsing. The LLM correctly extracts "7 days" from an email, but datetime.strptime has no format for relative durations. We built a regex fallback that catches patterns like "7 days", "7-day trial", and "in 7 days" and maps them to an absolute cancellation date using $d_{\text{cancel}} = \max(0,\ d_{\text{trial}} - 1)$.

Zero-click UX without false confidence. The hardest design challenge was showing a user that something autonomous just happened on their behalf in a way that feels trustworthy, not alarming. The five-second cosmetic delay, the pulsing amber "Agent navigating UI…" strip, and the hard flip to green on confirmed success were all deliberate choices to make the agentic loop feel legible and earned.


What's Next

Right now, ZeroCharge relies on manual email ingestion via our dashboard. The next evolution is full invisibility. We plan to integrate directly with Gmail/Outlook APIs using OAuth to passively monitor the inbox, and utilize AWS EventBridge to schedule Exhumation tasks exactly 24 hours before a trial expires, creating a truly zero-touch financial guardian.


Built With

  • Amazon Nova Act — autonomous browser agent
  • Amazon Nova 2 Lite (via Amazon Bedrock) — email parsing and structured extraction
  • FastAPI — async Python backend
  • Next.js + Tailwind CSS — frontend dashboard
  • Pydantic — request/response validation
  • Boto3 — AWS SDK for Bedrock

ZeroCharge — because the best subscription charge is the one that never happens.

Built With

  • amazon-nova-2-lite
  • amazon-nova-act
  • boto3
  • cursor
  • fastapi
  • next.js
  • pydantic
  • python
  • tailwind
Share this project:

Updates