ml-connector
MYOBServiceTitan

MYOB and ServiceTitan integration

MYOB handles accounting and general ledger for service businesses in Australia and New Zealand. ServiceTitan manages field-service dispatch, invoicing, and inventory for HVAC, plumbing, and electrical contractors. Connecting the two keeps your customer invoices, vendor bills, and payments aligned across both systems, so your technicians in ServiceTitan invoice on current rates, and the money flow back to MYOB without manual re-entry or reconciliation delays.

How MYOB works

MYOB Business API covers invoices, bills, purchase orders, supplier and customer contacts, GL accounts, items, and categories through REST with OData v3 query parameters. Authentication requires OAuth2 bearer token plus the company file username and password supplied as base64 in a separate header; access tokens expire in 20 minutes and refresh tokens last one week. MYOB imposes a rate limit of 8 requests per second and enforces maximum page sizes of 1000 records per call. MYOB does not support webhooks or push notifications, so connectors poll using OData $filter on LastModified timestamps to detect changes since the last sync. Every PATCH or PUT requires a RowVersion field from the prior read; stale RowVersion returns HTTP 409 conflict.

How ServiceTitan works

ServiceTitan exposes invoices, payments, purchase orders, inventory bills, vendors, customers, items, employees, and business units through REST APIs. Authentication uses OAuth2 client credentials with a Client ID, Client Secret, and required ST-App-Key header on every request; tokens remain valid for 15 minutes. ServiceTitan supports outbound webhooks with HMAC-SHA256 signature verification and covers events such as invoice.created, invoice.updated, payment.created, and customer.created with retries at 10 second, 30 second, 60 second, and 5 minute intervals. ServiceTitan rate-limits at 60 calls per second per app per tenant for standard APIs, and inventory bills are read-only; they are generated automatically when a purchase order is marked received.

What moves between them

The main flow runs bidirectionally. ServiceTitan invoices and payments push via webhook into MYOB as customer invoices and customer payments, keyed to matching contact records. MYOB bills and purchase orders poll into ServiceTitan as inventory bills and purchase orders for the matching vendor. Customer and vendor contact records sync in both directions so invoicing references valid parties on each side. GL accounts do not flow; ServiceTitan has no native GL mapping, so line items on invoices and bills reference ServiceTitan items and MYOB accounts separately.

How ml-connector handles it

ml-connector stores ServiceTitan client credentials and MYOB OAuth token plus company file credentials encrypted, and caches the ServiceTitan OAuth token for 15 minutes to avoid per-call re-authentication. On the MYOB side it presents the company file credentials in the required header on every request and refreshes the OAuth token when a 401 response indicates expiry. It verifies incoming ServiceTitan webhooks against the HMAC-SHA256 signature and queues them for processing. For MYOB polling, it uses OData $filter on LastModified to detect changes, and on PATCH or PUT it reads the RowVersion field from the prior GET so stale-version conflicts are handled gracefully. Customer and vendor matching is performed by contact name and optional email, since neither MYOB nor ServiceTitan expose external reference identifiers that span both systems. Invoices from ServiceTitan include line items with quantities and rates; ml-connector maps each to matching MYOB items by name and quantity type (service vs material), and allocates to the customer or job dimension if one exists in MYOB. Rate-limit backoff uses exponential retry with jitter to stay within MYOB's 8 request/second cap and ServiceTitan's 60 call/second limit.

A real-world example

A plumbing and electrical contractor in Sydney runs ServiceTitan for dispatch, job scheduling, and on-site invoicing, and MYOB for accounting and payroll. Before the integration, office staff manually entered each week's invoices from ServiceTitan into MYOB, re-keying customer names, job codes, and line items, and reconciled vendor bills from materials suppliers against MYOB at month-end. With ServiceTitan and MYOB connected, each invoice and payment completed by technicians in ServiceTitan flows automatically into MYOB as a customer invoice and receipt. Incoming AP bills from suppliers appear in ServiceTitan's inventory bill queue for matching against purchase orders. Technician billing is never delayed, and month-end reconciliation becomes a validation pass rather than a re-entry exercise.

What you can do

  • Sync ServiceTitan invoices and payments into MYOB as customer invoices and customer payments, matched to the correct customer contact.
  • Sync MYOB bills and purchase orders into ServiceTitan as inventory bills and purchase orders for the matching vendor.
  • Align customer and vendor contacts between systems so invoicing and billing reference valid parties on both sides.
  • Handle MYOB's dual OAuth2 plus company-file-credential authentication and RowVersion conflict resolution on updates.
  • Verify ServiceTitan webhook signatures and retry failed syncs with exponential backoff within both systems' rate limits.

Questions

How does the integration handle MYOB's company file credential requirement?
MYOB requires OAuth2 bearer token plus company file username and password supplied as a Base64-encoded header on every request. ml-connector stores both encrypted, caches the OAuth token and refreshes it when a 401 response indicates expiry, and supplies the company file credentials in the required header on each call. This dual-credential model means the integration requires the company file credentials to be shared with ml-connector; they are never logged or transmitted in the clear.
How are customers and vendors matched between MYOB and ServiceTitan?
MYOB and ServiceTitan both manage customer and vendor contact records but use different internal ID schemes. ml-connector matches by contact display name and optional email address; if a contact changes name, the match may break. Customers and vendors are synced bidirectionally, so new contacts added in either system propagate to the other when the integration runs. A mismatch typically indicates a contact was created in one system with a slightly different name (e.g., 'ABC Pty Ltd' vs 'ABC HVAC').
What happens when ServiceTitan generates an AP bill from a received purchase order?
ServiceTitan automatically creates an inventory bill when a purchase order is marked received (if auto-bill is enabled). This bill is read-only via the API and cannot be edited through ServiceTitan's API. ml-connector reads the bill and syncs it into MYOB as a bill, where it can be reviewed and approved for payment. If the bill needs adjustment, the change must be made in MYOB, not in ServiceTitan.

Related integrations

Connect MYOB and ServiceTitan

Free to use. Add your credentials, ping your real systems, and see if we fit.

Get started