Appearance
Contracts
A contract in OpsMerge defines the commercial relationship with a client: what they pay you per month, what they get for that money, and how usage feeds into billing.
Every paying client should have a contract. Without one, recurring billing has nothing to act on.
There is no "contract type"
A contract is a name, a date range, and a set of recurring lines. The commercial shape — per-asset, flat fee, time-and-materials, or any mix — comes entirely from which lines you put on it. There's no type field to pick, and nothing to change if the shape evolves: add, remove or deactivate lines.
| Shape you want | Lines you add |
|---|---|
| Per-asset | One line per asset class, quantity source = live asset count |
| Flat monthly fee | One line, quantity source = manual, quantity 1 |
| Time and materials | One line per billed service, quantity source = time entries, unit price = the hourly rate |
| Reseller / vendor subscriptions | Pax8-synced lines (managed by the sync, not edited by hand) |
| Metered usage (telecoms) | One line, quantity source = usage metered |
Hybrids are the normal case: a flat base fee, a per-endpoint line, and a T&M line for out-of-scope work all sit happily on one contract.
Creating a contract
Client → Contracts tab → + New contract.
Fields:
- Name (e.g. "Standard MSP — managed support").
- Start date and end date (end optional; "no end" means rolling).
- Auto-renew — whether the billing cycle rolls past the end date.
- Term (months) — informational only; the engine reads the end date.
- Billing position — arrears (bill a period after it ends, the default) or advance.
- Recurring lines — what to invoice each cycle. See below.
- Contract-wide discount (optional, percentage or fixed amount).
- Notes — for your team's reference, not shown to client.
A contract starts as a draft and bills only once it's active.
Recurring lines
The heart of a contract is its recurring lines — what gets billed every cycle.
Each line has:
- Name and description (shown on the invoice).
- Quantity source:
- Manual — a fixed quantity you set (e.g. "1 × Monthly Support" at £500).
- Live asset count (e.g. "Per-endpoint @ £15" with quantity = the count of billable assets at invoice time).
- Time entries — approved billable time on this client's tickets for the chosen service. Unit price is the hourly rate. See Time tracking.
- Usage metered — resolved from a connected usage source at invoice time.
- Pax8 subscription — written by the Pax8 sync; not operator-settable.
- Unit price.
- Service (required on a time-entries line — it's what matches the time to this line; also links to your accounting code, important for QuickBooks push).
- Tax code (for VAT).
- Billing frequency and due position for the line.
- Per-line discount (optional).
- Billing start date (optional per-line anchor) and end date.
At invoice time, OpsMerge computes the quantity for each "live" line from current data — your bill is always against today's state, not last month's snapshot. See Recurring invoices for how proration handles mid-cycle changes.
Per-asset details
The most common contract shape for MSPs. You charge per endpoint (or per M365 user, or per anything that counts as a billable asset).
Asset count is live: at invoice time, OpsMerge counts the client's billable assets and bills accordingly.
What counts as a billable asset depends on the line's quantity source — typically:
- Endpoint per-month: every Windows/Mac/Linux endpoint with the agent installed, excluding archived/excluded ones.
- M365 user per-month: managed M365 identities under a connected CIPP tenant.
- Network device per-month: routers, switches, APs added as RMM-monitored network assets.
Common patterns:
- One per-asset line covering everything: "Per managed asset @ £X" where the count = endpoints + network devices + M365 users.
- Multiple per-asset lines for different categories: "Per endpoint @ £X" + "Per M365 user @ £Y". More flexible pricing but more lines to manage.
Time and materials
Add a line with quantity source = time entries and pick the service it bills. The line's unit price is the hourly rate.
At invoice time that line sweeps up every time entry that is billable, not yet billed, stamped with that service, logged on a ticket belonging to this client, and sitting on an approved timesheet. Those hours become one invoice line, and the entries are marked as billed so they can never be invoiced twice.
Two consequences worth planning around:
- Unapproved time doesn't bill. Approval is a mandatory step, not a setting — see Time tracking.
- Time with no service doesn't bill. Set a Default T&M service at Settings → Time Tracking so timer-stop entries don't fall through the gap.
A client with no time-entries line is never invoiced for time, however much is logged. That's how you express "flat fee, unlimited support": bill the fee on a manual line and simply don't add a T&M line.
There are no included-hour blocks, overage rates, rollover, or pre-paid hour pools in OpsMerge. Time either matches a time-entries line and bills at that line's rate, or it doesn't bill at all — there's nothing in between to draw down.
Contract changes mid-cycle
OpsMerge handles mid-cycle changes by proration:
- Asset count changes — the next invoice prorates by day-fraction of the cycle (5 days at 100 assets, 25 days at 110 assets = prorated total).
- Contract upgrade/downgrade mid-cycle — typically wait until cycle end. If you change mid-cycle for some reason, the next invoice prorates the two phases.
SLA targets are not set here
A contract carries no SLA setting. Response and resolution targets come from SLA plans, configured at Settings → PSA → SLA plans and matched to a ticket on its priority, its type, and optionally a specific client — the most specific plan wins, and a client-specific plan beats a general one.
So "this client gets faster response times" is expressed as an SLA plan scoped to that client, not as a tier on their contract. A client with no matching plan simply gets no due-dates stamped on their tickets.
Ending a contract
Client → Contracts → contract → End.
Set the end date. From that date:
- No further recurring invoices generated.
- Any approved billable time not yet invoiced is still swept up by the final run — the time-entries sweep has no lower date bound, so nothing is orphaned by the contract ending.
- Tickets continue to work; SLA targets come from the SLA plans, not the contract, so they are unaffected.
You can have multiple contracts on a single client — useful when sliding from one structure to another. Just give them non-overlapping date ranges.
Voiding vs ending
- End: contract had a normal lifecycle; ends gracefully; everything to date is billable.
- Void: contract was a mistake or fraud; treat as never having existed.
Voiding a contract triggers reversals — including reversal of any recurring invoices issued under it (creates credit notes, releases any committed time, cancels Stripe charges). Use carefully.
Common patterns
"I want to charge a flat fee plus per-asset"
Two lines on one contract:
- Line 1: "Base monthly fee" — Fixed quantity 1, unit price £500.
- Line 2: "Per endpoint" — Live asset count, unit price £15.
"Different price per asset for servers vs workstations"
Two lines, both per-asset, with billing-category filters:
- Line 1: "Per workstation @ £12" — quantity source = endpoints with category = workstation.
- Line 2: "Per server @ £40" — quantity source = endpoints with category = server.
Asset categories are set per-asset (often automated based on OS edition). See Recurring invoices.
"Project work that's outside the contract"
Project work goes on tickets attached to a project, and each project carries its own billing model (time and materials, fixed price, milestone, retainer drawdown, or non-billable), set on the project itself.
Time on a project ticket is ordinary time: it still goes on a timesheet, still needs approval, and still bills through whichever time-entries contract line matches its service. If project work should bill at a different rate, give it its own service and add a second time-entries line at that rate.
Common issues
Recurring invoice ran but I expected a different total. Check the contract's recurring lines at the moment of invoice run. The "live asset count" lines pull the count at run time — if assets were added or removed since you set up the contract, the bill reflects that. The invoice itself has a breakdown showing the count used per line.
A time-and-materials line billed less than I expected. The sweep only picks up entries that are billable, unbilled, carry the line's service, and sit on an approved timesheet. An unapproved timesheet or a missing service is almost always the cause — Time tracking walks the checklist.
I changed a contract line and the next invoice still used the old value. Recurring lines snapshot at the moment of invoice generation. The change applies to the next run, not the one that already happened.
Next
- Recurring invoices — what contracts produce
- Billing & invoices — the broader invoicing surface
- Time tracking — how time is logged, approved, and turned into invoice lines