Source profileQuality 93/100

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.

Best for

    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

    PlatformStatusEvidenceWhat to check
    CodexNot declaredNo explicit evidencePortability before use
    Claude CodeNot declaredNo explicit evidencePortability before use
    CursorNot declaredNo explicit evidencePortability before use
    Gemini CLINot declaredNo explicit evidencePortability before use
    Open the compatibility checker

    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.

    Source-detected install commandSource
    npx skills add https://github.com/WYRE-AI/msp-claude-plugins --skill "msp-claude-plugins/quickbooks/quickbooks-online/skills/expenses"
    Safe inspection promptEditorial

    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

    1. 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
    2. 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…
    3. 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:
    4. 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.
    5. 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

    EvidenceSourceComputedTestedEditorial
    SignalValueEvidence typeMeaning
    Quality score93/100ComputedDocumentation, specificity, maintenance, and trust rules
    Repository stars42SourceRepository attention, not individual Skill quality
    Compatibility0 platformsSourceDeclared in the catalog source record
    Usage guideautomated source guideEditorialGenerated 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-invoices and qbo-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-accounts and xero-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-invoices or sherweb-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:

    PaymentTypeDescriptionMSP Example
    CashCash/bank paymentPetty cash for supplies
    CheckCheck paymentVendor payment by check
    CreditCardCredit card chargeSoftware subscription charge

    Bills vs Purchases

    EntityWhen to UsePayment Timing
    PurchaseExpense already paidImmediate (check, cash, credit card)
    BillVendor invoice receivedDeferred (pay later via BillPayment)

    MSP Expense Categories

    CategoryDescriptionExamples
    Software LicensesPer-seat or per-client licensesMicrosoft 365, antivirus, RMM seats
    HardwareEquipment for clientsServers, firewalls, workstations
    SubcontractorsOutsourced laborCabling, specialized consulting
    Cloud ServicesHosted servicesAzure, AWS, backup storage
    TelecomCommunication servicesInternet, VoIP, SIP trunks
    TrainingStaff certificationsVendor 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 CustomerRef on 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

    1. Allocate to customers - Always set CustomerRef on expense lines for per-client tracking
    2. Mark billable expenses - Use BillableStatus "Billable" for costs to re-invoice to clients
    3. Use consistent accounts - Map expense categories to standard QBO accounts
    4. Track by vendor - Create Vendor records for all suppliers and service providers
    5. Use Bills for deferred payment - Record vendor invoices as Bills, then pay with BillPayment
    6. Record software licenses monthly - Track per-seat costs monthly for accurate reporting
    7. Tag with PrivateNote - Store PSA references and internal project codes
    8. Review billable expenses - Regularly check for uninvoiced billable expenses

    See references/api.md for the complete endpoint reference.

    Related Skills

    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

    Computed 10045,960

    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

    Computed 10025,136

    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

    Computed 100147

    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

    Computed 100133

    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).