name: cleanupowl-automation description: Scans QuickBooks Online books via the CleanupOwl API to detect and fix bookkeeping issues. Use when the user mentions CleanupOwl, QuickBooks cleanup, QBO bookkeeping scan, fixing bookkeeping errors, running accounting scans, or applying solver fixes to flagged records.
CleanupOwl Automation
Purpose
This skill enables an agent to automatically clean and maintain QuickBooks books using the CleanupOwl API.
It allows you to:
- Run bookkeeping scans
- Analyze detected issues
- Apply fixes (solvers) to specific records
- Maintain books via repeatable workflows
Overview of where things live: the public site is cleanupowl.com; the signed-in web app and HTTP API host are app.cleanupowl.com, with routes under /tp/api/ (see API Reference).
When to Use This Skill
Prerequisites
Before using the CleanupOwl API, ensure the following:
- The user has a CleanupOwl account and can use the product in the browser at app.cleanupowl.com
- The user can create and scope API keys there (same app; keys are Bearer tokens per the reference)
- The user is on a subscription plan that includes API access
(Not every plan exposes
/tp/api/. If requests fail on billing or entitlements, the user upgrades or changes plan in CleanupOwl.) - The user has at least one QuickBooks Online company connected
- Full contract detail lives in API Reference
Verifying Connections
-
Call:
GET /tp/api/connections- Response shape:
data.connections(array); each item’s_idiscompanyIdon scan and solve calls—not the QBO realm id (externalId)
- Response shape:
-
If no connections are found (or the required company is missing):
- Call:
GET /tp/api/connect - Extract
data.connectionUrl - Ask the user to open that URL while logged into CleanupOwl so they can finish QuickBooks OAuth
- Call:
-
After successful authentication:
- Call
GET /tp/api/connectionsagain and readdata.connections[]._idfor later calls
- Call
Use This Skill When
- You need to scan accounting data for issues
- You want to fix bookkeeping errors programmatically
- You are building automated cleanup workflows
- You are assisting users with bookkeeping maintenance via API
- Steps should follow the scan → review → fix lifecycle (prep → apply, one row at a time)
Avoid Using This Skill When
- No QuickBooks company is connected
- The task is unrelated to bookkeeping cleanup
Key Concepts
-
Company ID (
companyId)
_idfromdata.connectionsonGET /tp/api/connections -
Scan (
scanId)
Background job: pull QBO data (unless sync skipped), run detectors, filldata.scan.resultswhendata.scan.statusiscompleted -
Issue (
issueId)
Stable id for a category of problem (keys underresults) -
Record (
recordId)
One flagged row; setrecordIdto a string matchingId,_id,entityId, oridon that row—see Identifying a row -
Solver (
solverId)
The fix path chosen after prep (or from solvers list); must match the issue or you getE_SOLVER_ISSUE_MISMATCH
High-Level Workflow
1. Get companyId from data.connections
2. POST /tp/api/scan/start
3. Poll GET /tp/api/scan/:scanId until data.scan.status is completed or failed
4. Review data.scan.results by issueId
5. Fix records: POST /tp/api/solve/prep → POST /tp/api/solve/apply
6. Optional: GET /tp/api/scans/:scanId/solves for audit trail
Flow 1: Run a Cleanup Scan
Step 1: Fetch Company ID
GET /tp/api/connections
- Extract
data.connections[]._id→companyId - Never use
externalId(realm) ascompanyId
Step 2: Start Scan
POST /tp/api/scan/start
Required:
companyId
Recommended:
period(or other body flags from the reference) to limit scope
Important:
- Scans are long-running;
POSTreturns immediately. Avoid redundant runs.
Step 3: Poll for Completion
GET /tp/api/scan/:scanId?companyId=...
Polling rules:
- Wait at least
data.pollAfterSecondsbefore the first poll (often 300) - Then exponential backoff: 5s → 10s → 20s → 30s (max 30s between tries)
- Stop when
data.scan.statusiscompletedorfailed
Step 4: Read Results
When data.scan.status is completed:
data.scan.resultsis a mapissueId→ bucket- Each bucket may expose
count,severity,records, and/ortable.rows
recordId: prefer the same rules as the reference (list vs table rows). For needsInput, options often come from recordFixOptions / metaFixOptions after prep, not from the raw scan row alone.
Flow 2: Fix a Record
Always run PREP before APPLY
Step 1: Prepare Fix
POST /tp/api/solve/prep
Purpose:
- Row-level solvers and
userInputhints - Risk flags before writing to QBO
Check risk flags (critical)
| Flag | Meaning | Agent action |
|---|---|---|
hasSolvers | false — no solver for this row/issue | Do not apply; read message if present |
hasLinkedTransactions | Linked QBO txns (e.g. payment ↔ invoice) | Proceed carefully |
resolvedByOtherFix | Already fixed elsewhere | Skip |
needsRevalidation | QBO changed vs scan | New scan before apply |
entityConflicts | Same entity under multiple issues | Resolve conflicts first |
Step 2: Apply Fix
POST /tp/api/solve/apply
Include:
scanId,issueId,recordId,companyIdsolverId(from prep when needed)- Optional
userInput
This call writes to QuickBooks Online.
Step 3: Handle response
| Scenario | Action |
|---|---|
success: true with data.action (typical apply success) | Done; read data.message |
success: true with data.needsInput: true | Not a failure (HTTP 200). Build userInput from missingFields / userInputSchema, then POST apply again with the same ids |
success: false | Branch on error.code; use error.message for logging only |
Step 4: Audit fixes
GET /tp/api/scans/:scanId/solves?companyId=...
Use to:
- Track solve attempts
- See
action,success,solverId,executedAtper entry
Flow 3: Ongoing cleanup routine
Weekly routine
GET /tp/api/billingif fix limits matter- Start scan → poll → read
results - Prioritize high severity, then medium; skip low if appropriate
- Prep → apply per row; review history with
/scans/:scanId/solves
Monthly deep clean
- Broader
periodor full company scan per product guidance - Compare severities across runs
- Clear remaining buckets; watch for new
issueIdvalues fromGET /tp/api/issues
Best practices for agents
- Call
solve/prepbeforesolve/applyunless you already have a validatedsolverIdanduserInput - Honor
pollAfterSecondsand backoff caps - Pass
companyIdon every scan GET, history, and solves query as required - Treat
needsInputas a normal apply round-trip, not an exception path forsuccess: false
Common mistakes (avoid)
- Polling every second instead of waiting
pollAfterSecondsand backing off - Using
externalIdor a label instead ofdata.connections[]._idforcompanyId - Skipping prep when
recordFixOptionsmatter - Applying against an old
scanIdafter QBO changed (E_ENTITY_MODIFIED,needsRevalidation) - Treating
needsInputas failed apply solverIdthat does not matchissueId
Error handling strategy
- Read
error.code(stable); avoid logic onerror.messagealone - Map to recovery: reconnect QBO (
E_QBO_AUTH_FAILED), re-scan (E_ENTITY_MODIFIED, archived scan), fix payload (E_MISSING_COMPANY_ID, mismatch codes), billing (E_FIX_LIMIT_EXCEEDED) - Details and HTTP semantics: Errors, Common
error.codevalues, Common mistakes
Support and bugs
If something cannot be resolved with docs, retries, or reconnecting QuickBooks, or looks like a defect, point the user at human support.
Contact: support@cleanupowl.com
When: repeated failures after normal recovery, inconsistent API behavior, access or billing blocked in-app, or suspected product bug.
Optional context for the user: account and in-app help from app.cleanupowl.com; general product info at cleanupowl.com.
Email template
Subject: [CleanupOwl] <short topic> — e.g. [CleanupOwl] API error on solve/apply
Body (fill in brackets):
What happened:
[One or two sentences]
What I expected:
[Expected behavior]
What I got instead:
[Actual behavior, including any error message text]
Context (include what you can):
- Endpoint or action: [e.g. POST /tp/api/solve/apply]
- Approximate time (with timezone): [when it occurred]
- error.code or HTTP status (if any): [values]
- companyId / scanId / issueId (only if the user is comfortable sharing): [optional]
Steps to reproduce (if known):
1. [...]
Keep the email factual; do not invent details.
Quick reference
Relative paths are under /tp/api/ on app.cleanupowl.com.
| Action | Endpoint |
|---|---|
| QBO connect URL | /connect |
| List companies | /connections |
| Issue catalog | /issues |
| Start scan | /scan/start |
| Poll scan | /scan/:scanId |
| Scan history | /scan/history |
| Prep | /solve/prep |
| Apply | /solve/apply |
| Audit solves | /scans/:scanId/solves |
| Billing | /billing |
Agent decision logic
- No finished
scanIdfor the task → start scan (then poll) - Scan not
completed/failed→ poll with backoff - Scan
completed→ readresults, pick row, prep → apply - Apply returns
needsInput→ enrichuserInput, POST apply again success: false→error.code-driven recovery- Product or API bug → Support and bugs (template + support@cleanupowl.com)
Companion files in this repo
All paths are valid from the repository root:
| File | Role |
|---|---|
| api-reference.md | Full HTTP reference |
| README.md | Integration kit overview |
| cleanupowl-tp-api-openapi.yaml | OpenAPI 3 spec |
| cleanupowl-tp-api-postman-collection.json | Postman collection |
| examples/basic.md | Short curl examples |
| examples/advanced.md | Prep/apply, errors, targeted scans |