WYRE-AI/msp-claude-plugins/msp-claude-plugins/quickbooks/quickbooks-online/skills/expenses/SKILL.md
QuickBooks Online Expenses
QuickBooks Online expense entities: Purchase (check, cash, credit card), Bill for accounts payable, BillPayment, and Vendor. Covers account-based vs item-based expense lines, per-client cost allocation via CustomerRef and BillableStatus, expense categorization, query syntax, error codes, and MSP profitability analysis patterns.
- Source repository stars
- 42
- Declared platforms
- 0
- Static risk flags
- 0
- Last source update
- 2026-08-28
- Source checked
- 2026-08-28
Decision brief
What it does: where it fits
QuickBooks Online expense entities: Purchase (check, cash, credit card), Bill for accounts payable, BillPayment, and Vendor. Covers account-based vs item-based expense lines, per-client cost allocation via CustomerRef and BillableStatus, expense categorization, query syntax, error codes, and MSP profitability analysis patterns.
Not for
- Tasks that require unconfirmed production actions or broad system permissions.
- Environments where the pinned source and install steps cannot be inspected.
Compatibility matrix
Platform support, with evidence labels
| Platform | Status | Evidence | What to check |
|---|---|---|---|
| Codex | Not declared | No explicit evidence | Portability before use |
| Claude Code | Not declared | No explicit evidence | Portability before use |
| Cursor | Not declared | No explicit evidence | Portability before use |
| Gemini CLI | Not declared | No explicit evidence | Portability before use |
Installation
Inspect first. Install second.
The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.
npx skills add https://github.com/WYRE-AI/msp-claude-plugins --skill "msp-claude-plugins/quickbooks/quickbooks-online/skills/expenses"Inspect the Agent Skill "QuickBooks Online Expenses" from https://github.com/WYRE-AI/msp-claude-plugins/blob/5005f73ba2f52cd299f58aa6bb79f4e70ae87103/msp-claude-plugins/quickbooks/quickbooks-online/skills/expenses/SKILL.md at commit 5005f73ba2f52cd299f58aa6bb79f4e70ae87103. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.
Workflow
What the source asks the agent to do
- 01
Anti-triggers
Money coming in — this skill is accounts payable. Client billing and
Money coming in — this skill is accounts payable. Client billing andThe books are in Xero, not QuickBooks — use xero-accounts andThe distributor's own charge detail — Pax8 and Sherweb hold the - 02
Key Concepts
The Purchase entity covers direct expenses paid immediately or via credit card:
The Purchase entity covers direct expenses paid immediately or via credit card:QBO supports assigning expenses to customers, enabling per-client profitability analysis. Use the CustomerRef field on line items to allocate costs to specific MSP clients.A Purchase requires PaymentType, AccountRef.value (the bank or credit card account it was paid from), and at least one Line. A Bill requires VendorRef.value and Line. Per-client allocation lives on the line detail, not… - 03
Expense Types (Purchase Entity)
The Purchase entity covers direct expenses paid immediately or via credit card:
The Purchase entity covers direct expenses paid immediately or via credit card: - 04
Bills vs Purchases
Review the “Bills vs Purchases” section in the pinned source before continuing.
Review and apply the “Bills vs Purchases” source section. - 05
MSP Expense Categories
Review the “MSP Expense Categories” section in the pinned source before continuing.
Review and apply the “MSP Expense Categories” source section.
Permission review
Static risk signals and limitations
No configured static risk pattern was detected
This is not proof of safety. Runtime behavior, indirect dependencies, and hidden external systems are outside the static scan.
Evidence record
Why each signal appears
| Signal | Value | Evidence type | Meaning |
|---|---|---|---|
| Quality score | 93/100 | Computed | Documentation, specificity, maintenance, and trust rules |
| Repository stars | 42 | Source | Repository attention, not individual Skill quality |
| Compatibility | 0 platforms | Source | Declared in the catalog source record |
| Usage guide | automated source guide | Editorial | Generated or reviewed according to the visible evidence level |
Pinned source
Provenance and original SKILL.md
- Repository
- WYRE-AI/msp-claude-plugins
- Skill path
- msp-claude-plugins/quickbooks/quickbooks-online/skills/expenses/SKILL.md
- Commit
- 5005f73ba2f52cd299f58aa6bb79f4e70ae87103
- License
- Apache-2.0
- Collected
- 2026-08-28
- Default branch
- main
View the original SKILL.md
QuickBooks Online Expense Management
Overview
Expenses in QuickBooks Online are tracked through two primary entities: Purchase (for direct expenses like checks, credit card charges, and cash payments) and Bill (for accounts payable -- vendor invoices you owe). For MSPs, expense tracking is critical for per-client profitability analysis: tracking software licenses, hardware costs, subcontractor fees, and third-party service costs against the revenue each client generates.
Anti-triggers
- Money coming in — this skill is accounts payable. Client billing and
cash receipts are
qbo-invoicesandqbo-payments. "Bill" is the trap: a QBO Bill is something the MSP owes, while a PSA "bill" is usually something a client owes. - The books are in Xero, not QuickBooks — use
xero-accountsandxero-invoices. - The distributor's own charge detail — Pax8 and Sherweb hold the
line-level cost of cloud licences before it is entered as a bill here.
Use
pax8-invoicesorsherweb-billing. - Technician time as a cost — labour cost is not a Purchase or Bill;
time originates in the PSA (
autotask-time-entries,connectwise-psa-time-entries) and lands here only as payroll. - The profitability answer itself — per-client margin is a report over
these records, not a query against them; use
qbo-reports.
Key Concepts
Expense Types (Purchase Entity)
The Purchase entity covers direct expenses paid immediately or via credit card:
| PaymentType | Description | MSP Example |
|---|---|---|
Cash | Cash/bank payment | Petty cash for supplies |
Check | Check payment | Vendor payment by check |
CreditCard | Credit card charge | Software subscription charge |
Bills vs Purchases
| Entity | When to Use | Payment Timing |
|---|---|---|
| Purchase | Expense already paid | Immediate (check, cash, credit card) |
| Bill | Vendor invoice received | Deferred (pay later via BillPayment) |
MSP Expense Categories
| Category | Description | Examples |
|---|---|---|
| Software Licenses | Per-seat or per-client licenses | Microsoft 365, antivirus, RMM seats |
| Hardware | Equipment for clients | Servers, firewalls, workstations |
| Subcontractors | Outsourced labor | Cabling, specialized consulting |
| Cloud Services | Hosted services | Azure, AWS, backup storage |
| Telecom | Communication services | Internet, VoIP, SIP trunks |
| Training | Staff certifications | Vendor certs, training courses |
Per-Client Cost Tracking
QBO supports assigning expenses to customers, enabling per-client profitability analysis. Use the CustomerRef field on line items to allocate costs to specific MSP clients.
Key Fields
A Purchase requires PaymentType, AccountRef.value (the bank or credit card
account it was paid from), and at least one Line. A Bill requires
VendorRef.value and Line. Per-client allocation lives on the line detail, not
the header: AccountBasedExpenseLineDetail.CustomerRef.value plus
BillableStatus ("Billable", "NotBillable", "HasBeenBilled"). TotalAmt and
Balance are read-only; SyncToken is required on updates.
See references/fields.md for the complete Purchase, Bill, and Vendor field reference.
API Patterns
Query Purchases (Expenses)
GET /v3/company/{realmId}/query?query=SELECT * FROM Purchase WHERE PaymentType = 'CreditCard' AND TxnDate >= '2026-01-01'&minorversion=73
Authorization: Bearer {access_token}
Accept: application/json
Common Queries:
-- All credit card expenses in a date range
SELECT * FROM Purchase WHERE PaymentType = 'CreditCard' AND TxnDate >= '2026-01-01' AND TxnDate <= '2026-01-31'
-- Expenses for a specific vendor
SELECT * FROM Purchase WHERE EntityRef = '42'
-- All expenses in a month
SELECT * FROM Purchase WHERE TxnDate >= '2026-02-01' AND TxnDate <= '2026-02-28' ORDERBY TxnDate DESC
-- All bills (accounts payable)
SELECT * FROM Bill WHERE Balance > '0' ORDERBY DueDate ASC
-- Bills for a specific vendor
SELECT * FROM Bill WHERE VendorRef = '42' AND Balance > '0'
-- All vendors
SELECT * FROM Vendor WHERE Active = true ORDERBY DisplayName
Create Purchase (Credit Card Expense)
POST /v3/company/{realmId}/purchase?minorversion=73
Content-Type: application/json
Authorization: Bearer {access_token}
Software license expense allocated to a client — note AccountRef on the header
is the funding account (credit card), while AccountRef inside the line detail
is the expense account:
{
"PaymentType": "CreditCard",
"AccountRef": { "value": "41" },
"EntityRef": { "value": "42", "type": "Vendor" },
"TxnDate": "2026-02-15",
"Line": [{
"Amount": 450.00,
"Description": "Microsoft 365 Business Premium - 30 seats - Acme Corp - February 2026",
"DetailType": "AccountBasedExpenseLineDetail",
"AccountBasedExpenseLineDetail": {
"AccountRef": { "value": "60" },
"CustomerRef": { "value": "123" },
"BillableStatus": "Billable"
}
}],
"PrivateNote": "Monthly software licenses for Acme Corp"
}
See references/examples.md for the multi-line request body, the curl equivalent, and a Create Vendor payload.
Create Bill (Vendor Invoice)
{
"VendorRef": {
"value": "42"
},
"TxnDate": "2026-02-10",
"DueDate": "2026-03-12",
"Line": [
{
"Amount": 2400.00,
"Description": "Cabling project - Acme Corp new office build-out",
"DetailType": "AccountBasedExpenseLineDetail",
"AccountBasedExpenseLineDetail": {
"AccountRef": { "value": "62" },
"CustomerRef": { "value": "123" },
"BillableStatus": "Billable"
}
}
],
"PrivateNote": "Subcontractor cabling for Acme Corp office expansion"
}
Pay a Bill (BillPayment)
{
"VendorRef": {
"value": "42"
},
"PayType": "Check",
"CheckPayment": {
"BankAccountRef": { "value": "35" }
},
"TotalAmt": 2400.00,
"Line": [
{
"Amount": 2400.00,
"LinkedTxn": [
{
"TxnId": "789",
"TxnType": "Bill"
}
]
}
]
}
Common Workflows
Per-Client Expense Report
async function getClientExpenses(customerId, startDate, endDate) {
// Get all purchases with line items allocated to this customer
const purchases = await queryAll('Purchase',
`TxnDate >= '${startDate}' AND TxnDate <= '${endDate}'`
);
const clientExpenses = [];
for (const purchase of purchases) {
for (const line of purchase.Line || []) {
const detail = line.AccountBasedExpenseLineDetail || line.ItemBasedExpenseLineDetail;
if (detail?.CustomerRef?.value === customerId) {
clientExpenses.push({
date: purchase.TxnDate,
vendor: purchase.EntityRef?.name || 'Unknown',
description: line.Description,
amount: line.Amount,
billable: detail.BillableStatus === 'Billable',
category: detail.AccountRef?.name
});
}
}
}
return {
customer: customerId,
period: `${startDate} to ${endDate}`,
expenses: clientExpenses,
total: clientExpenses.reduce((sum, e) => sum + e.Amount, 0)
};
}
Monthly Software License Tracking
async function recordMonthlyLicenses(month, licenseData) {
const results = [];
for (const license of licenseData) {
const purchase = await createPurchase({
PaymentType: 'CreditCard',
AccountRef: { value: license.creditCardAccountId },
EntityRef: { value: license.vendorId, type: 'Vendor' },
TxnDate: `${month}-15`,
Line: [{
Amount: license.seats * license.perSeatCost,
Description: `${license.productName} - ${license.seats} seats - ${license.customerName} - ${month}`,
DetailType: 'AccountBasedExpenseLineDetail',
AccountBasedExpenseLineDetail: {
AccountRef: { value: license.expenseAccountId },
CustomerRef: { value: license.customerId },
BillableStatus: license.billable ? 'Billable' : 'NotBillable'
}
}],
PrivateNote: `Auto-recorded: ${license.productName} for ${license.customerName}`
});
results.push({
customer: license.customerName,
product: license.productName,
amount: license.seats * license.perSeatCost,
purchaseId: purchase.Id
});
}
return results;
}
Profitability Analysis
async function clientProfitability(customerId, startDate, endDate) {
// Revenue: sum of invoice line items for this customer
const invoices = await qboQuery(
`SELECT * FROM Invoice WHERE CustomerRef = '${customerId}' AND TxnDate >= '${startDate}' AND TxnDate <= '${endDate}'`
);
const revenue = (invoices.QueryResponse.Invoice || [])
.reduce((sum, inv) => sum + inv.TotalAmt, 0);
// Costs: sum of expense line items allocated to this customer
const expenses = await getClientExpenses(customerId, startDate, endDate);
return {
customerId,
period: `${startDate} to ${endDate}`,
revenue,
costs: expenses.total,
profit: revenue - expenses.total,
margin: revenue > 0 ? ((revenue - expenses.total) / revenue * 100).toFixed(1) + '%' : 'N/A'
};
}
Outstanding Bills Summary
async function getOutstandingBills() {
const result = await qboQuery(
"SELECT * FROM Bill WHERE Balance > '0' ORDERBY DueDate ASC"
);
const bills = result.QueryResponse.Bill || [];
const today = new Date().toISOString().split('T')[0];
return bills.map(bill => ({
vendor: bill.VendorRef.name,
amount: bill.TotalAmt,
balance: bill.Balance,
dueDate: bill.DueDate,
overdue: bill.DueDate < today
}));
}
Error Handling
- Customer allocation is per line, not per transaction. There is no
header-level
CustomerRefon Purchase or Bill — a report that reads only the header will show zero client cost. - 610 Object Not Found on a Purchase create is usually a stale or inactive
AccountRef/EntityRef; the fault Detail names the field, the message does not. - Inactive references fail silently in intent. Deactivating a vendor or account leaves existing transactions intact but rejects new ones referencing it.
- 6240 Duplicate Name applies to Vendor
DisplayName, which shares a namespace with Customer and Employee names in QBO.
See references/errors.md for the full error-code and validation tables plus a recovery pattern.
Best Practices
- Allocate to customers - Always set CustomerRef on expense lines for per-client tracking
- Mark billable expenses - Use BillableStatus "Billable" for costs to re-invoice to clients
- Use consistent accounts - Map expense categories to standard QBO accounts
- Track by vendor - Create Vendor records for all suppliers and service providers
- Use Bills for deferred payment - Record vendor invoices as Bills, then pay with BillPayment
- Record software licenses monthly - Track per-seat costs monthly for accurate reporting
- Tag with PrivateNote - Store PSA references and internal project codes
- Review billable expenses - Regularly check for uninvoiced billable expenses
See references/api.md for the complete endpoint reference.
Related Skills
- QBO Customers - Customer allocation targets
- QBO Invoices - Re-invoicing billable expenses
- QBO Payments - Bill payments
- QBO Reports - P&L and expense reports
- QBO API Patterns - API reference
Frequently asked questions
What to verify before installation and use
What does the QuickBooks Online Expenses source document cover?
QuickBooks Online expense entities: Purchase (check, cash, credit card), Bill for accounts payable, BillPayment, and Vendor. Covers account-based vs item-based expense lines, per-client cost allocation via CustomerRef and BillableStatus, expense categorization, query syntax, error codes, and MSP profitability analysis patterns.
How do I install QuickBooks Online Expenses?
The source record exposes this install command: npx skills add https://github.com/WYRE-AI/msp-claude-plugins --skill "msp-claude-plugins/quickbooks/quickbooks-online/skills/expenses". Inspect the command and pinned source before running it.
Alternatives
Compare before choosing
coreyhaines31/marketingskills
ab-testing
When the user wants to plan, design, or implement an A/B test or experiment, or build a growth experimentation program. Also use when the user mentions "A/B test," "split test," "experiment," "test this change," "variant copy," "multivariate test," "hypothesis," "should I test this," "which version is better," "test two versions," "statistical significance," "how long should I run this test," "growth experiments," "experiment velocity," "experiment backlog," "ICE score," "experimentation program
alirezarezvani/claude-skills
app-store-optimization
App Store Optimization (ASO) toolkit for researching keywords, analyzing competitor rankings, generating metadata suggestions, and improving app visibility on Apple App Store and Google Play Store. Use when the user asks about ASO, app store rankings, app metadata, app titles and descriptions, app store listings, app visibility, or mobile app marketing on iOS or Android. Supports keyword research and scoring, competitor keyword analysis, metadata optimization, A/B test planning, launch checklist
equinor/neqsim
neqsim-professional-reporting
Engineering deliverable quality — the nine analytical-depth moves (contributor ranking, adjudicating the source document, quantitative rule-outs, robustness crossover, conservatism direction, discriminating test), results.json schema, figure→discussion→linked_results traceability, evidence matrices, assumptions/gaps registers, citation conventions, KaTeX math formatting, units consistency, executive-summary structure, AACE class declaration. USE WHEN: producing a task report, a PEPR/M1/root-caus
JasonColapietro/suede-creator-skills
suede-ab-testing
Suede-owned experimentation discipline for hypotheses, sample sizing, test duration, significance, and repeatable experiment programs. Use when comparing variants, deciding whether a result is reliable, or building an experiment backlog and cadence. NOT FOR: analytics instrumentation (use suede-analytics), post-click conversion diagnosis (use suede-site-alchemy), or writing the variant copy itself (use suede-copy).