What gets tracked per job

The cost schema — the columns in your Sheet.

Every job (row in the projects tab) tracks the following cost fields. Nothing hidden, nothing inferred — every number is visible and editable in the Sheet you own.

Column Source How it's captured
labor_hours_totalCrew SMSSum of (OUT timestamp − IN timestamp) across every tech on the job
labor_costComputedlabor_hours_total × tech-specific billable rate (config) — supports per-tech rates + OT premium
materials_costCrew SMS or photoTech texts PARTS J-id: ... OR photographs receipts; Claude parses + logs line items
subcontractor_costOwner SMS or formOwner texts SUB J-id: ... when subcontractor cost is incurred
overhead_costOwner SMS or configOverhead allocation, permit fees, disposal, equipment rental, anything that doesn't fit the direct-cost categories above (this is the "indirect cost" line)
total_costComputedlabor + materials + subs + other
quoted_priceIntake / change ordersInitial SOW + signed change orders (updated automatically when a change order signs)
gross_margin_dollarsComputedquoted_price − total_cost
gross_margin_pctComputedgross_margin_dollars ÷ quoted_price × 100

A real job row

What this looks like on a Tuesday afternoon.

Job J-1248. Restoration shop. Cat 2 water loss, single-family residence. Day 4 of a structural drying cycle. Owner glances at the Sheet at 2pm.

// projects tab · row 247 · J-1248
job_id: J-1248
customer: Coastal Stone & Surfaces (Civic Center tower)
scope: Cat 2 water loss · south lobby · dishwasher line
stage: in_progress · day 4 of 7-10
labor_hours: 34.5 (Eddie 18 · Phil 11 · Marco 5.5)
labor_cost: $1,725 @ $50/hr blended rate
materials_cost: $420 (3× containment poly $90 · plastic sheeting $80 · zipper kit $40 · drywall sample bag $30 · sanitizer + biocide $180)
sub_cost: $0 (no sub yet — projected $400 for HVAC duct sanitization on day 6)
other_cost: $0
total_cost_so_far: $2,145
quoted_price: $8,400 (initial scope) · +$2,200 approved supplement = $10,600 total
gross_margin_dollars: $8,455 (projected at close)
gross_margin_pct: 79.8% (high — restoration insurance work)
// last updated: 14:22 PT · auto from Eddie's OUT message at 14:10

No CSV import. No "sync running." No screen the owner has to log into. The numbers are in the Sheet, the Sheet is in the owner's Drive, the owner glances at it whenever they want.

Aggregate views

How do I see job profitability in OpsLight?

Weekly aggregate (Friday digest)

Total revenue, total cost, gross margin $ and %, average margin per job. Trends week-over-week. Anomalies flagged (margin under your floor on a specific job — investigate).

Monthly aggregate (in monthly PM status emails)

Per-customer / per-PM margin. Per-trade margin if your shop covers more than one trade. Per-tech contribution. Per-TPA margin (restoration) — critical for deciding which TPA relationships to keep and which to drop.

Per-job postmortem

Any job that closes below your margin floor (config — defaults to 25%) triggers an automatic owner-summary email: what went over, why (labor blew the estimate? unbudgeted sub? scope creep without signed change order?), what to bid differently next time.

Quarterly roll-up (Q3 2026 roadmap)

Capex review + margin trends. Equipment utilization vs margin contribution (which dehumidifier earned its keep? which truck is on schedule for replacement?). Coming Q3 2026.

QuickBooks + Zoho + Xero + FreshBooks integration

One CSV. Your bookkeeper takes it from there.

OpsLight ships three CSV export endpoints, formatted for direct import:

GET /export/projects.csv → job-cost roll-up, QuickBooks Items + Class compatible
GET /export/time-tracking.csv → billable hours per job, per tech, per day
GET /export/invoices.csv → invoiced jobs, payment status, AR aging
All token-gated. Friday afternoon bookkeeper workflow: hit the URL, save the CSV, run the QBO import wizard, done.

We don't replace QuickBooks. We feed it. The accounting integration that ServiceTitan and Jobber charge $100-$200/month per for is a free CSV pull in OpsLight. Your accountant uses the tool they're certified in (QuickBooks ProAdvisor for QBO, etc.); we just hand them the data.

Honest about what's NOT in v1

What OpsLight job costing doesn't do (yet).

  • No multi-warehouse inventory cost roll-up. See /inventory/ for the honest framing. We track materials USED on jobs; we don't track materials on shelves.
  • No real-time P&L dashboard. The Friday digest is the routine touchpoint. The Sheet is live, but we don't ship a vertical-stacked-charts dashboard.
  • No automatic payroll integration. Time-tracking CSV exports to your existing payroll system (Gusto, ADP, Paychex, etc.). We feed; we don't replace.
  • No deep KPI customization. The standard reports cover ~80% of small-shop questions. If you need a custom dashboard of 15 specific KPIs, that's a different category of tool (Tableau / Looker Studio / Domo) and your Sheet exports clean into all of them.
  • No automatic profit-share or commission calculations. Roadmap Q4 2026 for shops on commission models. Vote at /what-it-is/ if this matters to you.

If any of those are dealbreakers, OpsLight is the wrong fit and we'll tell you which competitor to look at. ServiceTitan covers all of the above for the 20+ tech shop with a $30K-60K year-one budget; for the 1-15 person shop priced out of that math, we cover the 80% that's load-bearing.

Common questions

What people ask about job costing in OpsLight.

Does OpsLight track per-job cost and margin?

Yes. Every job in your Google Sheet has columns for labor hours (per crew member, per shift), labor cost (hours × your per-tech rate), materials cost, subcontractor cost, and quoted price. OpsLight computes total job cost + gross margin per job automatically. Aggregate views ship in the Friday weekly digest and monthly status emails.

How does OpsLight capture labor hours per job?

Via the SMS crew-check-in system — tech texts IN [job-id] on arrival, OUT [job-id] [notes] on departure. Timestamps logged automatically. Hours computed from the timestamp delta. Per-tech billable rate stored in your config. No app to install, no time-clock terminal.

How are material costs captured?

Two paths. (1) Tech texts a parts-used message at job close: PARTS J-1248: 1x R-410A 25lb $180, 2x filter 20x25x4 $48 each. OpsLight parses + logs. (2) Tech photographs the receipt + texts it; Claude OCRs the receipt photo and logs the line items. Both paths SMS-based, no app.

Can OpsLight export job-cost data to QuickBooks?

Yes. Token-gated CSV export at /export/projects.csv?client=YOUR_SHORTNAME returns the full job-cost schema in QuickBooks Online's expected import format. Same for time-tracking and invoices. Zoho Books, Xero, FreshBooks all supported with the same CSV path.

Does OpsLight handle change orders that affect job cost?

Yes. When scope changes mid-job, OpsLight auto-drafts a change order from the SMS thread, generates the PDF on your letterhead, and updates the quoted-price column once signed. Margin column recomputes automatically. The Friday digest flags any open change orders awaiting signature.

What about supplements for restoration shops?

Supplements work the same as change orders, with a separate workflow for the carrier-pushback case (see /for/restoration/). Supplement-recovery rate is tracked per-job and per-TPA. If a supplement gets denied, OpsLight drafts the push-back memo citing IICRC S500 and your prior comparable jobs.

Can I see margin live, or only at week-close?

Live. The Google Sheet IS the database — open it anytime on your phone or laptop. The Friday digest aggregates it for the week. Owners typically only look mid-week when something feels off.

Want to see this configured for your shop?

20 minutes on a call. We'll set up a mock projects tab with your trade's cost categories and your QuickBooks export format. You ask anything.

Apply to the founding cohort See the reports