Docs/Guides/Extending the Service module
◆ Guide

Extending the Service module.

The data model, custom work order types, service webhooks, parts and labor extensibility, and how to wire it all up to an external shop management system.

  • Work orders, labor lines, parts lines, warranty claims
  • Define your own work order types in admin or via API
  • Six service webhooks from created through warranty-filed
  • Integrate Mitchell 1, Shop-Ware, or a home-grown shop tool
In this guide
  1. The service data model
  2. Custom work order types
  3. Service webhooks
  4. Parts catalog extension
  5. Labor rate configuration
  6. External shop-management integration
  7. Reporting extensions

1. The service data model

Four top-level resources. Everything else hangs off these.

Work orders belong to a location_id and optionally a service_bay_id. Time clock punches are separate (time_punch) and link to labor lines at commit.

2. Custom work order types

BoaterOS ships with standard types (PDI, commission, warranty, comeback, detail, storage, winterization, de-winterization, survey-repair). Add your own under Service → Types → New or through the API:

POST /v1/service/work-order-types
{
  "code": "hurricane_haul_out",
  "label": "Hurricane haul-out",
  "default_bay": "bay_yard_3",
  "default_labor_rate_code": "yard",
  "default_flat_rate_minutes": 120,
  "required_fields": ["hull_id", "length_ft", "beam_ft"],
  "checklist_template_id": "chk_hurricane_v2",
  "visible_to_customer_portal": true,
  "invoice_tax_code": "tx_fl_service"
}

Required fields block WO creation if absent; checklists attach a step-through list to the tech's iPad view. The new type is immediately available to scheduling, dispatch, and billing.

3. Service webhooks

Event When it fires
work_order.created A new WO opened. Payload has the full resource plus the triggering contact/hull.
work_order.labor_added Tech added or updated a labor line. Good for real-time shop dashboards.
work_order.parts_ordered Parts line changed from `requested` → `ordered`. Payload includes supplier PO.
work_order.completed WO closed and invoiced. Total parts+labor+tax is finalized.
work_order.warranty_filed A warranty claim was filed with the OEM. Payload includes OEM claim ID.
work_order.reopened Closed WO reopened (comeback, warranty, correction). Original WO id retained.
POST /v1/service/work-orders
curl https://api.boater.os/v1/service/work-orders \
  -H "Authorization: Bearer $BOATEROS_KEY" \
  -d '{
    "type_code": "hurricane_haul_out",
    "hull_id": "hull_YDV48219",
    "contact_id": "cnt_YTG9210",
    "scheduled_for": "2026-06-01T13:00:00-04:00",
    "notes": "Customer requests storm-prep checklist."
  }'

4. Parts catalog extension

The parts catalog ships with Mercury, Yamaha, Volvo Penta, Suzuki, Honda, Garmin, and Raymarine pre-loaded (SKU, list price, supplier). Add custom SKUs with a supplier mapping:

POST /v1/service/parts
{
  "sku": "SHOREPWR-30A-50",
  "description": "30A shore power cord, 50 ft, yellow",
  "supplier_id": "sup_marinco",
  "supplier_sku": "199119",
  "cost_cents": 14900,
  "list_cents": 21900,
  "tax_class": "parts",
  "min_stock": 4,
  "reorder_point": 6
}

Suppliers with EDI feeds (Land 'N' Sea, Payne's, Wholesale Marine, and most OEMs) accept POs automatically. For the rest, BoaterOS emails a PDF PO with a reply-tracking address.

5. Labor rate configuration

Labor rates live in a small table keyed by (rate_code, skill_tier, effective_from). Rate codes are free-form — we see dealers split by "retail," "warranty," "internal," "yard," "commission." Skill tiers (apprentice / tech / master) multiply the base rate. Rates are time-versioned so historical WOs always invoice at the rate in effect on the date of service.

6. External shop-management integration

If you run Mitchell 1 or Shop-Ware alongside BoaterOS, use the service webhooks as your source of truth and push state changes back via the REST API. A common pattern:

We test this path against Mitchell 1 and Shop-Ware in CI; a reference adapter is open-sourced at github.com/boateros/shop-adapters.

7. Reporting extensions

The standard service reports (utilization, effective labor rate, warranty recovery, parts margin, comeback rate) live in the admin. For anything custom, three options: (1) the /v1/reports/service/* endpoints return the same aggregates as JSON, (2) the daily S3 export dumps the full normalized schema to Parquet, and (3) read-only Postgres replicas are available on the Fleet plan for direct BI tool connection.

Warning. Don't compute effective labor rate client-side from raw labor lines. We apply rate versioning, warranty splits, and internal-vs-retail allocation server-side; reproducing it is how people file tickets saying "your numbers are wrong" when their own numbers are wrong.

◆ Next step

Service is where the margin is.

Extend it to fit how your shop actually runs. The API surface is documented end-to-end, and our engineers are a Slack away.

Book a demo Back to docs