Outcome-Based Professional Services
The outcome-based services pricing pattern: instead of billing for hours worked or seats provisioned, you bill when defined milestones are delivered - a project phase signed off, a healthcare encounter completed, an SLA target met, a regulatory filing accepted. The economics align supplier and client around results instead of effort. The hard parts are defining the milestones unambiguously, capturing the evidence that triggers each charge, and getting both sides to agree the milestone has actually been hit.
Real-world examples. Consulting firms (McKinsey/BCG/Bain billing on project phases), creative agencies (per-deliverable invoicing), legal practices (matter-based billing), healthcare providers (per-encounter or per-procedure billing), construction (progress-payment milestones), software-as-a-service-with-success-fee variants (charge X% of customer's revenue gain), regulated services (charge per accepted regulatory filing). Common shape: contract defines a list of milestones with associated fees, each milestone has acceptance criteria, charge fires when the criteria are met, both parties sign off on the milestone, audit trail tracks the evidence end-to-end.
The shape of the problem
Outcome-based billing replaces "regular calendar invoice" with "event-driven invoice," which surfaces unique constraints:
- Milestone definition is the contract. What exactly counts as "phase 1 delivered"? Acceptance criteria need to be unambiguous, machine-checkable where possible, and tied to evidence both sides can verify.
- Asymmetric trigger sources. Some milestones trigger automatically (SLA target met, regulatory acceptance received via API), some require manual approval (client signs off on a deliverable), some need both (system says it's done, client confirms before charge fires).
- Evidence trail. When the customer disputes the charge three months later, you need to show the sign-off, the supporting documents, and the timestamp. Compliance auditors expect the same.
- Partial milestones. Phase 1 delivered at 90% completion - charge 90% now, 10% on full delivery? Many contracts allow tiered acceptance.
- Milestone sequencing and dependencies. Phase 2 can't bill until Phase 1 is accepted. Phase 3 fires only if Phase 2 hits a specific KPI.
- Hold-back / retention. Common in construction: 10% of every milestone held back until the entire project is signed off, released as a final settlement.
Kontorion blueprint
| Concern | Kontorion primitive |
|---|---|
| Milestone definition with fee | One-shot invoice line per project phase |
| Evidence trail | Milestone metadata |
Build it
1. Set up the customer and project
Code
2. Define the milestones for the engagement
A typical 3-phase consulting project:
Code
percentage is a JSON number representing a fraction of the resolved product price - it
must be greater than 0 and at most 1 (so 20% is 0.20, not 20). At trigger time the
milestone bills resolved_price × percentage. Each milestone references a product_id that
must exist in the subscription's plan-version snapshot.
3. Configure approval workflow for milestone acceptance
Roadmap — not yet available
Approval workflows are planned but not currently wired into the running API. The
/approval-workflows routes are disabled pending feature completion, and approval
workflows are not integrated with milestone triggers — see the note in step 4 about
how POST .../trigger behaves today. The request shape below is shown for forward
planning and is subject to change before release.
When the feature ships, you will register a reusable workflow template and route milestone triggers through it. The current template shape is:
Code
Note that the real CreateWorkflowTemplateRequest accepts name, entity_type,
trigger_action, steps, and optional description, on_timeout, and on_rejection.
Each step uses step_number, name, approver_roles / approver_user_ids,
min_approvals, timeout_hours, and notify_on_start. There is no trigger_conditions
field, and entity_type must be one of the supported entities (for example SUBSCRIPTION,
INVOICE, PRODUCT) — there is no BILLING_MILESTONE entity type today.
4. Trigger Phase 1 sign-off
When the consulting team finishes the assessment and the client signs off, trigger the
milestone. The trigger endpoint takes the subscription and milestone IDs in the path and
no request body - the milestone must be in PENDING status and its subscription must
be ACTIVE:
Code
Triggering is synchronous and not gated by any approval workflow today: the milestone
resolves the product's price, applies its percentage, calculates tax, and immediately
creates a draft invoice with a milestone line. The milestone moves to TRIGGERED and the
response carries the milestone plus the new invoice_id:
Code
Capture sign-off evidence (signed PDF URL, approver, timestamp) in the milestone's
metadata at creation time - the trigger call itself does not accept or store any body.
5. Inspect the milestone
Read a single milestone to see its current status, when it was triggered, the invoice it
generated, and the evidence you stored in metadata:
Code
Code
List every milestone on the engagement with
GET /v1/subscriptions/sub_globex_eng/milestones. For org-wide change history (who created
or triggered what, and when), query the platform audit events feed - there
is no dedicated /audit sub-resource on milestones.
6. Apply 10% retention across the engagement
Roadmap — not yet available
Retention / holdback escrow is not implemented. There is no counterparties resource,
internal_escrow account type, or withholding_rules in the API today. The example below
is a forward-looking sketch and does not correspond to a working endpoint.
For projects with retention/holdback (common in regulated industries and construction-style engagements), the planned model would withhold a percentage of each milestone payment and release it on final sign-off:
Code
Until this ships, model retention manually - for example, set each milestone percentage
to the net (post-retention) fraction and trigger a separate final milestone for the held-back
remainder once the engagement is signed off.
Variations
- Time-and-materials hybrid. Combine outcome-based milestones with usage events for billable hours. Some deliverables fire milestone charges, while underlying T&M still bills monthly per timesheet.
- Healthcare per-encounter billing. Each encounter is a one-shot milestone with the procedure code in metadata; payer rules (configured per
customer.metadata.payer_id) determine reimbursement amount and timing. - SLA-conditional charges. Milestone fires only when the SLA dashboard reports target hit (e.g., "99.9% uptime achieved this month"). Use a webhook from your monitoring system as the trigger source.
- Success-fee model. Charge X% of measured customer revenue gain. Milestone evaluates a customer-reported metric (or pulls from an integrated analytics system) and creates a percentage-based invoice line.
- Regulatory acceptance billing. Charge fires when a regulator's API confirms a filing is accepted (e.g., FDA submission accepted, HMRC return processed). Webhook from your filing system carries the regulator's confirmation ID.
- Bonus + clawback. Bonus milestone fires on KPI hit; if KPI deteriorates within N months, an automatic credit note claws back a portion. Implement via paired milestones and time-bounded conditions.
What you don't have to build
- Milestone trigger orchestration (
POST /v1/subscriptions/{subscriptionId}/milestones/{id}/triggerplus an HMAC-signed webhook variant atPOST /v1/webhooks/billing-milestones/{id}) - Synchronous price resolution, tax calculation, and draft-invoice line generation on trigger
- Per-engagement custom acceptance criteria and evidence references (live in milestone
metadata) - KPI-based bonus calculations (external event payloads carry the metrics)
Planned but not yet available (do not build against these today):
- Multi-party sign-off workflows with timeouts and escalation (approval-workflows routes are disabled, and not wired to milestone triggers)
- Enforced dependency graphs between milestones —
depends_on_milestoneis free-formmetadatayou record yourself; the API does not block out-of-order triggers - Retention escrow accounting and timed release
Next steps
- Billing Milestones - the milestone primitive used throughout this guide
- Approval Workflows - dual sign-off and gating (roadmap; routes currently disabled and not wired to milestone triggers)
- Subscriptions - the engagement container
- Custom Fields - storing acceptance criteria and evidence references