Exercise 3 of 3 — The Big One: QBO Bill Import Middleware
This is the graduation exercise. You're going to build a middleware application that connects to QuickBooks Online, authenticates via OAuth, and imports vendor bills through the API. If you finish this, you can build anything. Estimated time: 1.5–2 hours.
What is an API?
An API (Application Programming Interface) is a set of rules for how software talks to other software. When you log into your bank's website, you're using a user interface (UI) — buttons, forms, visual stuff. An API is like a UI for software. Your code sends a structured request ("create a bill with this vendor for this amount") and QBO processes it, just as if someone had typed it in manually.
What is OAuth?
OAuth is how QBO knows your app is allowed to access the account. Think of it like a valet key — you give the valet a special key that starts the car but won't open the trunk. OAuth gives your app limited access to QBO without sharing the owner's password. The user clicks "Authorize," QBO confirms, and your app gets a token (a temporary pass) to make requests.
Sandbox vs. Production:
- Sandbox — A fake QBO company with fake data. Free, safe, can't break anything. This is where you develop and test. You can create fake bills, fake vendors, fake everything.
- Production — A real QBO company with real data. Requires Intuit to review and approve your app. This is where your middleware would actually run for a client.
You're starting with the sandbox. Same code works in both — the only difference is the URLs and credentials.
What a real build looks like:
We have built a full invoice processing middleware for a client. It ingests PDFs, parses line items, maps products to QBO inventory items, learns vendor patterns over time, validates everything, then pushes finished bills into QuickBooks. It handles BOLs, freight calculations, pricing lookups, and drift detection.
Yours does one thing: import a bill. That's the seed. Everything else grows from it.
The middleware runs on Python using Flask (a lightweight web framework). The exercises so far were just HTML files — this one is a real application with a server.
To talk to QuickBooks through the API, you need a developer account with Intuit (the company that makes QBO). This is free and gives you a sandbox environment to play with.
Create an app:
Get your credentials:
After creating the app, find the section called Keys & OAuth (sometimes labeled "Keys & credentials," or tucked under "Development Settings"). Look for those words rather than an exact button. You need three things from here:
Set the redirect URI:
This tells Intuit where to send the user after they authorize your app. Since your app runs on your own computer:
Find your sandbox company:
Intuit automatically creates a sandbox QBO company for testing. It has fake vendors, fake invoices, fake everything.
• Client ID
• Client Secret
• Redirect URI (http://localhost:5000/callback)
• Sandbox Company ID
Keep these in your text file. You'll paste them into Claude Code in a moment.
First, have Claude set up the project structure. This prompt includes your Intuit credentials — replace the placeholders with your actual values:
Now for the big build. This prompt tells Claude to create the entire Flask application. It's longer than previous prompts because there's more to build, but the pattern is the same — describe what you want, Claude builds it.
pip install), say yes.
python app.py. You should see something like * Running on http://127.0.0.1:5000 in the output.
The server is running. Now let's connect it to your QBO sandbox.
You should see a dashboard page with a "Connect to QuickBooks" button (or something similar). The status should show "Not Connected."
This should redirect you to Intuit's authorization page. You'll log in with your Intuit developer account and authorize the app to access your sandbox company.
After authorizing, Intuit sends you back to your app (the redirect URI). Your app captures the authorization code, exchanges it for tokens, and saves them.
• Redirect URI mismatch — make sure
http://localhost:5000/callback is exactly what you entered in the Intuit portal• Wrong Client ID or Secret — double-check the .env file
• Make sure you're using the sandbox credentials, not production
The moment of truth. You're going to create a bill in QBO through your middleware.
Now verify it actually made it into QBO:
Think about what happened: you typed information into YOUR app, your app talked to QBO's servers through the API, and a bill appeared in QuickBooks. No manual data entry. No copy-pasting. Software talking to software.
This is what middleware does. This is the pattern for everything.
You've been working in the sandbox. When you're ready to go to production (real QBO data for a real client), here's what changes:
- App review: Intuit reviews your app before it can access real QBO companies. This takes a few days to a few weeks depending on complexity.
- Credentials: You get a separate production Client ID and Client Secret. You update the .env file.
- Environment flag: Change
QBO_ENVIRONMENT=sandboxtoQBO_ENVIRONMENT=productionin your .env file. - Redirect URI: You add a production redirect URI in the Intuit portal (same URL if running locally, or your server's URL if hosting it).
- The code itself: Doesn't change. Same Flask app, same API calls, same everything.
Update your memory log with everything you accomplished:
Ctrl+C. To start it again later, navigate to the folder and run python app.py.
You've built three things of increasing complexity:
- A standalone tool (Eisenhower Matrix) — HTML only, no backend
- A connected form (Homework Email) — HTML + Google Apps Script backend
- A real middleware (Bill Importer) — Python + Flask + OAuth + QBO API
The pattern is always the same:
- Create a project folder with CLAUDE.md and a context/ folder (PROJECT.md, JOURNAL.md)
- Describe what you want to Claude
- Review the plan, approve it, let Claude build it
- Test, customize, iterate
- Update context/JOURNAL.md before closing
Ideas for what to build next:
- Add PDF upload to the bill importer — attach the vendor invoice to the QBO bill
- Build a client reporting dashboard that pulls data from QBO and visualizes it
- Create a scheduling tool for your consulting sessions
- Build a client portal where your clients can see their own data
- Connect to other APIs — Mailchimp, HubSpot, Stripe, whatever your clients use
Every one of these follows the same pattern you just learned. The only difference is which API you're talking to and what the UI looks like. Claude handles the technical details. You handle the vision.