Overview
Invoice Chaser answers the owner's weekly question: "Who hasn't paid me, and what should I do about each one?" It replaces the manual loop of opening QuickBooks, scrolling the AR aging report, copying customer emails, writing follow-up messages by hand, and forgetting who got contacted last week.
The skill is built around a human-in-the-loop approval gate. It gathers overdue invoices, segments them by severity, drafts tier-appropriate follow-up emails, then surfaces all drafts for the owner to approve, edit, or skip before anything sends. Nothing leaves the owner's email account without explicit go-ahead.
Use it on a weekly cadence (or daily when cash is tight). For hands-off operation, enable auto_schedule to run automatically with configurable approval levels.
Supports multi-channel reminders (email + SMS), customer group segmentation (different strategies per customer type), and interval-based scheduling (reminders at specific days before/after due date).
Workflow
- Tier Segmentation: three tiers by days overdue. Friendly (1 to {{friendly_threshold_days}}), Firm ({{friendly_threshold_days}}+1 to {{firm_threshold_days}}), Final Notice ({{firm_threshold_days}}+1 and beyond). Configurable; exactly one tier per invoice.
- Order-of-Magnitude Outlier: any invoice ≥10x the median of the OTHERS (or ≥10x the next-largest); skip the check with fewer than 4 invoices. Flag EVERY match with a "heads up - unusually large, possible data error" annotation. Never block, drop, or reshape it. It stays drafted, shown in full, sendable; the owner decides at the gate. The ledger figure stands.
- Review Scrutiny: tag each draft HEADS UP (outlier amount, or overdue resting on stale QB data), WORTH A GLANCE (Final Notice, unusually large, first-ever Final Notice, VIP/large account), or ROUTINE. Tags only order/annotate. They never block, hold, drop, or reshape any draft.
- Approval Gate: decision-card checkpoint. Every draft's FULL body (recipient, subject, message) is shown first, attention-worthy ones ordered first and flagged. Owner approves/edits/skips and chooses STAGE (Gmail drafts) vs SEND. Outlier flags are scrutiny, not blocks. Nothing stages/sends until the owner sees full drafts and gives explicit go-ahead; SEND carries its log + reminder obligations as one action. Default is do-nothing.
- Follow-up History: per-customer log (date, tier, invoice, message ID). Drives prior-contact references, duplicate suppression within {{duplicate_window_days}}, and tier escalation. Authoritative store is structured LOCAL JSON. MAY also append to QB notes (append-only: read, append, update, never overwrite); QB notes are not the source of truth for duplicate suppression.
- Email Provider: Gmail or Outlook, detected at runtime. If both connected, ask which. Never send from both in one run.
- Payment Instructions: how customers pay, included in every chase as a "How to pay" line. Any free-text method (pay URL, PayPal/Stripe/Venmo/Zelle/Cash App, bank/ACH, check address, phone, email). Captured ONCE, stored as a SHARED business memory ("business payment instructions for customer invoices") reused by every invoicing skill. {{payment_link}} overrides memory. NEVER fabricated, and in particular never a hand-built QuickBooks/Intuit pay URL. Substitute each invoice number into any {invoice}/{invoiceid}/{id} placeholder. If none on file and owner skips, send without one and note it.
- Cross-Channel Payment: payments made outside QuickBooks (bank/check/cash) may not be reconciled yet, so Firm/Final Notice emails carry a soft "may have already paid" caveat (owner can disable if books are reconciled).
- Reminder Channel: Email (default), SMS (Twilio; shorter/urgent), or Both (use sparingly). If Twilio not connected, fall back to email-only silently.
- Customer Groups: named segments overriding tone, thresholds, channel, schedule. One group per customer; ungrouped use global defaults.
- Reminder Schedule (Interval-Based): alternative to tiers. Post-due touchpoints (e.g. +3, +7, +14, +21, +30) mapped to tone (+1–14 Friendly, +15–30 Firm, +31+ Final). When
scheduleis set, only draft the next unsent interval per Follow-up History. Values must be ≥0; pre-due reminders belong to Deposit Collection.
<Workflow description="End-to-end overdue invoice chase: gather, segment, draft, approve, send, log." tools=[recall_memories, save_to_memory, file_read, file_write] triggers=["who hasn't paid me", "what's overdue", "chase unpaid invoices", "send payment reminders", "run collections follow-up"]
[Agent] Pull all overdue invoices from QuickBooks using
quickbooks__QueryEntities(entity: Invoice). Query for invoices with a positive balance, then compute days overdue relative to today in-memory. Validate every invoice has a positive balance and a due date in the past. Flag any with missing customer reference. Also pull customer notes for each customer with overdue invoices (query the Customer entity viaquickbooks__QueryEntitiesand read its notes/memo field). These notes contain chase history from prior runs, payment arrangements, disputes, and owner context - they are needed in Step 5 (Rule 2 precondition) and Step 8 (prior-notification display). Pull them now so they are available without a second round-trip. If auth error: prompt owner to re-link QuickBooks. If 0 results: exit early with "No overdue invoices - you're caught up."[Think] Note that QuickBooks data may not reflect payments received outside the system (bank transfers, checks, cash). These unreconciled payments mean some "overdue" invoices may already be paid. The soft-payment caveat in Firm and Final Notice templates accounts for this. No tool call needed - proceed to Step 3.
[Agent] Segment invoices by tier per the Tier Segmentation definition:
- 1 to {{friendly_threshold_days}} days → Friendly
- {{friendly_threshold_days}}+1 to {{firm_threshold_days}} days → Firm
- {{firm_threshold_days}}+1 days and beyond → Final Notice
Filter out any invoice below {{minimum_invoice_amount}} per Rule 3. Produce tier counts for the summary. Validate: every remaining invoice has exactly one tier assigned. No overlap. If fails: If tier segmentation cannot be completed (for example a threshold input is missing or invalid), report the specific problem to the owner and stop before drafting rather than guessing a tier.
[Agent] Pull customer contact info using
quickbooks__QueryEntities(entity: Customer). Call once and join in memory - do not call per-invoice. Extractcustomer_email,customer_display_nameper invoice. Default to billing email; fall back to primary if no billing email exists. Validate: flag invoices with missing or malformed email - these are surfaced separately in Step 6. If a single customer lookup fails: continue with the rest, report failures at the end.[Think] Read prior-contact history from BOTH the local Follow-up History (structured state from Step 11 on prior runs) AND each customer's QuickBooks notes/memo (per Rule 2). This is a PRECONDITION to drafting - if QB notes were not read, do not proceed to Step 7. If either shows a same-tier notice within the last {{duplicate_window_days}} days, mark the invoice
skip_duplicate, exclude it from drafting, and report why in Step 6. For invoices contacted at a lower tier previously, note the prior outreach date for the draft. Per Rule 18 (mandatory), net any unapplied customer credit (credit memo, overpayment, or deposit balance) against that customer's overdue total: chase only the net owed, and if a credit fully covers the balance mark the customercovered_by_creditand exclude them from drafting (surface in Step 6). If the connector does not expose credit balances, proceed on invoice balances and note in Step 6 that credits were not checked. Per Rule 21 (mandatory), check each customer's/invoice's QuickBooks notes for a dispute, payment arrangement / promise-to-pay, recent human outreach, or a do-not-contact / on-hold marker; if found, mark the itemskip_noteswith a plain reason and surface it in Step 6 (never chase over a dispute or do-not-contact). If notes are unavailable, note that they were not checked. Run the order-of-magnitude outlier check (per <Definition - Order-of-Magnitude Outlier>) and tag each remaining invoice's review scrutiny (HEADS UP / WORTH A GLANCE / ROUTINE) per <Definition - Review Scrutiny> for annotation ONLY - never to block, hold, or exclude. Use the QuickBooks last-sync time for the stale-data flag. Recall the owner's saved payment instruction viarecall_memories(query "business payment instructions for customer invoices" - a SHARED setting any invoicing skill may have saved) unless {{payment_link}} was provided; if neither exists, mark first-run payment setup needed in Step 6. Per Rule 22, flag any invoice that newly crossed a 30 / 60 / 90 day overdue threshold since the last run, for the escalation callout in Step 6.[Ask user] Present the run summary. Per Rule 23: BEFORE showing the numbers, check whether customers already received a same-tier notice recently (within {{duplicate_window_days}}) based on QB notes. Split them into two groups: "already notified" (waiting for response) and "never chased" (or last notice outside the window). If there are already-notified customers, present the split and a decision card:
If total send count exceeds 15, warn per Rule 12. First-run payment setup (per <Definition - Payment Instructions>): if no saved payment link was found in Step 5 and {{payment_link}} was not provided, ask the owner ONCE: "How should customers pay you? Anything works - a payment link or portal URL, PayPal/Venmo/Zelle/Cash App, bank or ACH details, a check mailing address, a phone number to call and pay, or an email to send payment to. Paste whatever you use and I'll include it in every reminder and remember it for next time. Or say 'skip' to send without one." Record the owner's answer as a SHARED business memory so every invoicing skill reuses it, e.g. "Noted: the business's payment instructions for customer invoices are (shared across invoicing skills - Invoice Chaser, Job-to-Invoice, Deposit Collection; do not re-ask)." Do not re-ask once it is saved here or by any sibling invoicing skill. If the owner skips, remember that too and proceed without a payment instruction. Present the choice as a decision card:
[Agent] Before drafting, confirm payment setup is resolved per Rule 17: a link is on file, was just provided, or the owner explicitly skipped. If it is NOT resolved - including when the owner gave a narrowing instruction like "draft the 5" without addressing payment - ask the one-time payment-setup question (Step 6) first, then draft. Apply the {{tone}} input (and any customer_groups override); never ask the owner about tone or style (Rule 19). Draft tier-appropriate emails for all approved invoices following the tier and Rule 20 formatting (short, human, correct line breaks, plain text; in particular, put NO blank line between the sign-off word and the owner's name - write "Thanks," and then the name on the very next line). Reference Follow-up History in Firm and Final Notice drafts where prior outreach exists. Append the soft-payment caveat to Firm and Final Notice emails per Rule 7 unless the owner disabled it. Include the owner's payment link or instructions (per <Definition - Payment Instructions>) in every draft when one is on file, as a clear "How to pay" line, substituting each invoice's number into any placeholder in the link; use the saved or captured value and never fabricate one. Group recurring invoices by customer per tier - one email per customer per tier, listing all overdue invoices at that tier level. A customer with 2 Friendly and 1 Firm invoice receives 2 emails: one Friendly covering both, one Firm covering the third. Validate: payment setup was resolved before drafting; each draft has non-empty subject, body, and recipient; body references actual invoice number and amount, includes the payment link/instructions when on file, and follows Rule 20 formatting (human wording; sign-off word and owner name on two separate adjacent lines; NO occurrence of the banned robotic phrasing about not receiving "payment or a response to previous communications"); every Firm and Final Notice draft includes the soft-payment caveat per Rule 7 unless the owner disabled it. No template placeholders remain. If a draft fails for one invoice: mark it
draft_failed, continue with others. Drafting only produces drafts; never call a send tool in this step. Always continue to Step 8 to present them for approval.[Agent, then Ask user] Present drafts for review - this is mandatory and the core safety gate. Precondition: the Step 6 gate passed and payment setup is resolved.
FIRST, present a decision card for HOW to review the drafts:
Then, based on the owner's choice, render the drafts IN FULL - meaning the actual email body (recipient, subject, full message text), NOT a summary table or list of names/amounts. A table of customer names is NOT a draft. The draft IS the email text the customer will receive. Do NOT show only a list or a summary table of who will get an email. Render each draft's recipient, subject, and full message text in chat. Group recurring invoices by customer per tier. A "draft the top N" instruction means draft and SHOW those N IN FULL, then wait - it is NOT a list and it is NOT approval to send. Order any flagged drafts first and annotate each with its flag (HEADS UP / WORTH A GLANCE) per <Definition - Review Scrutiny>. Flags are for extra scrutiny, not a block - flagged drafts are sendable like any other.
For EACH draft, show prior notification history from the customer's QuickBooks notes (read in Step 5). If a prior chase entry exists, annotate that draft with a one-line context: "Previous: [tier] sent on [date]". This gives the owner immediate visibility into how recently and how often this customer has been contacted, right next to the draft they are deciding on.
Lead with one line: "{{total}} drafts ready for your review ({{flagged_count}} flagged for extra scrutiny, shown first). Nothing sends or stages until you say so." Then show every draft IN FULL with its prior-notification annotation (if any).
Present the choice as a decision card per draft (or per batch). Each card notes prior contact:
For batches where no customer has prior history, a single batch card is acceptable:
When ANY draft has prior notification history, use per-draft cards so the owner makes an informed per-customer decision with the prior contact date visible. When none have history, the batch card is fine.
STOP and wait for that choice in a LATER turn. Never stage or send in the same turn you present the drafts. A "draft the top N" instruction means draft and SHOW those N in full, then wait; it is NOT approval to stage or send. If {{dry_run}} is true: show the full drafts as preview only and confirm nothing will be staged or sent, per Rule 10. End workflow after this step. Validate: every draft that will stage or send was shown IN FULL with its prior-notification context; the owner made an explicit decision-card choice; default is do-nothing. If fails: If the drafts cannot be rendered in full, do not stage or send anything; report the display problem to the owner and stop, since approval requires seeing the full drafts.
[Decide] Act on the owner's Step 8 decision-card choice:
- dry_run true, or the owner only previewed or chose "Cancel": nothing is staged or sent; summarize what would have happened and end.
- "Stage drafts": create the approved drafts in Gmail via the Gmail connector's draft action (never call the send tool); confirm exactly which drafts were staged and that nothing was sent. Do not log a 'sent' record or set a reminder for staged-only drafts. End.
- "Send all" (Send + log + remind): continue to Step 10. This single choice covers the send AND its obligations in Steps 10-12 - they are one action carried out in the same response, not optional follow-ups.
[Agent] Send the approved drafts. Precondition (per Rule 1): the drafts were presented IN FULL in Step 8 this run AND the owner gave an explicit "Send all" AFTER seeing them. If the drafts were not shown in full, or the owner only said "draft" or only chose a scope like "top 10", do NOT send - return to Step 8. Send only the specific approved drafts via the detected Email Provider using
gmail.send_email(oroutlook.send_email). Pause briefly between sends to avoid rate limits. On any send failure, retry once before reporting. The send is NOT complete on its own: in the SAME response, immediately continue to Step 11 (log) and Step 12 (reminder) before writing any recap or confirmation. Do not end the turn, and do not show Step 13, with logging or the reminder still unresolved. Validate: every email sent was shown to and approved this run; each send returns success (message ID or 202 accepted); Steps 11 and 12 are carried out in this same response. If sends fail after retry: report which failed with reason. Do not retry indefinitely.[Agent, then Ask user] Log every send and confirm - REQUIRED, in the SAME response as Step 10 (do not skip, do not defer to a later turn). For each sent email you MUST do BOTH: (a) write a structured record to local skill state { customer_id, invoice_number, tier, channel, message_id, sent_at (ISO-8601) } - the authoritative duplicate tracker the next run reads (Step 5 / Rule 2); AND (b) append a chase entry to the customer's QuickBooks notes via a read-append-update pattern: READ the existing notes first (the customer may have other notes there - payment arrangements, personal context, etc.), APPEND your new line to the end (e.g. "2026-06-08: Final Notice sent via email, Invoice #14, $3,200.00, 47d overdue. Follow-up reminder set for 2026-06-11."), then UPDATE the notes with the full combined text. NEVER overwrite or replace existing notes - only append. Attempt the QB note for every send; if the tool is unavailable or fails, state that explicitly.
After logging, present the result:
Validate: a structured local record exists for every sent email, and a QB note write was attempted for each (success or failure noted and shown to owner). Step 13 may NOT be shown until this is done. If logging fails: note it for the run summary, do not block the run (per Rule 9) - but still record the attempt; logging failing is not permission to skip logging.
[Agent] Set the follow-up reminder - REQUIRED, in the SAME response as Step 10 (this is part of the "Send + log + remind" action the owner chose; do not treat the send as finished without it). If {{followup_reminder_days}} is greater than 0, create a one-time scheduled reminder via
create_scheduled_agent, {{followup_reminder_days}} days out (default 3), to re-check the invoices chased this run and escalate any still unpaid. For a small batch (5 or fewer customers) you MAY set one reminder per customer ("Invoice # for ($) was chased on and may still be unpaid - check payment and escalate to the next tier if needed."); for a larger batch, set a single consolidated reminder listing the chased customers, invoices, and amounts. When it fires, the reminder prompts the owner (or the next run) to re-check payment and escalate any still-unpaid invoice to the next tier (Friendly -> Firm -> Final); it never auto-sends. Skip ONLY if {{followup_reminder_days}} is 0. Validate: a reminder (per-customer or consolidated) was scheduled for the chased set, or {{followup_reminder_days}} is 0 and the skip was noted. Step 13 may NOT be shown until this is resolved. If fails: fall back to a calendar event; if that also fails, tell the owner the follow-up date to set manually and treat the step as resolved. Never block the run on a reminder failure (per Rule 9).[Agent] Present the final summary. Precondition: Steps 11 (logging) and 12 (reminder) are resolved. Never show this summary - or any "done" / "all sent" confirmation - while logging or the reminder is still unresolved. Include: emails sent (count, recipients, tiers); emails skipped (with reasons); logging status (local record written, and whether the QB note write succeeded or failed); the follow-up reminder set (date and scope); and any failures encountered. If this was a dry run, reiterate that nothing was sent. If fails: If the summary cannot be assembled, tell the owner directly which emails were sent, logged, and reminded so the run outcome is not lost.
<Workflow description="Set up or modify automated reminder schedule." tools=[] triggers=["set up automatic reminders", "schedule payment chasing", "automate invoice reminders", "change reminder schedule"]
[Ask user] Determine the automation preferences:
- Frequency: daily, weekly (default), or biweekly?
- Auto-action: draft_only (default), send_friendly_auto, or notify_only?
- Customer scope: all customers or a specific group?
- Channel: email, sms, or both?
Present current schedule if one exists. Allow modification. If fails: If the owner does not specify preferences, re-ask for the frequency, auto-action, scope, and channel before continuing.
[Decide] Validate configuration:
- If 'send_friendly_auto' selected, confirm: "This will automatically send Friendly-tier reminders without your approval. Firm and Final Notice will still require approval. Confirm?"
- If 'sms' or 'both' selected, verify Twilio is connected. If not, warn and offer email-only fallback.
[Agent] Register or update the scheduled task using
agent_management.create_scheduled_taskoragent_management.update_scheduled_task. Set:- Frequency per owner's choice
- Run day/time per owner's choice (defaults: {{auto_schedule_day}} at {{auto_schedule_time}} in owner's timezone)
- Action mode per owner's choice
- Customer group filter if specified If fails: If the scheduled task cannot be registered or updated, report the specific error to the owner and confirm no automation was set.
[Agent] Confirm setup to owner with summary of what will happen and when. Include how to modify or cancel. If fails: If the confirmation summary cannot be produced, tell the owner the schedule was saved and provide the key settings directly.
<Workflow description="Sen
…(truncated)