ml-connector
Wave AccountingServiceTitan

Wave Accounting and ServiceTitan integration

Wave Accounting tracks invoices and customers for your small business. ServiceTitan manages field service dispatch and jobs. Connecting the two keeps your customer and invoice data flowing from Wave into ServiceTitan so your field teams always see the latest billing history and customer details. New invoices in Wave appear in ServiceTitan linked to the matching customer, and customer changes flow in the same direction so your service team works with current information.

How Wave Accounting works

Wave Accounting exposes invoices, customers, products, accounts, transactions, and vendors through a GraphQL endpoint at https://gql.waveapps.com/graphql/public over HTTPS. Authentication uses OAuth2 with an access token valid for 2 hours and a refresh token (offline_access scope required). Wave publishes webhooks for invoice creation, updates, and payment, plus customer and product changes; ml-connector can subscribe to these webhooks or poll the GraphQL API. Webhook signatures use HMAC-SHA256 and must be verified within a 5 minute replay window. Bills and purchase orders are not exposed through the Wave GraphQL API; Wave is primarily invoicing and accounting records for the connected business.

How ServiceTitan works

ServiceTitan exposes invoices, payments, inventory bills, purchase orders, customers, vendors, jobs, and appointments through REST APIs at https://api.servicetitan.io/{namespace}/v2/tenant/{tenantId}/. Authentication uses OAuth2 client credentials with a token valid for 15 minutes; every API call requires the ST-App-Key header in addition to the bearer token. ServiceTitan enforces a rate limit of 60 calls per second per application, and a 100 second server timeout. AP Bills are read-only and auto-generated from purchase orders. ServiceTitan publishes webhooks with HMAC-SHA256 signatures for job, invoice, payment, customer, and appointment events. The tenant ID must appear in every URL path; omitting it returns a 404 error.

What moves between them

Wave invoices and customer records flow into ServiceTitan on a schedule or as webhooks arrive from Wave. Each invoice pulled from Wave is matched to the corresponding customer in ServiceTitan by email or name, then posted as a ServiceTitan invoice linked to that customer. Customer updates from Wave update the matching ServiceTitan customer record. The direction is Wave to ServiceTitan only; ServiceTitan invoices and jobs do not flow back to Wave.

How ml-connector handles it

ml-connector handles Wave's GraphQL endpoint and OAuth2 token refresh, storing the refresh token encrypted and requesting a new access token when the current one expires. On the ServiceTitan side, it constructs the per-tenant URL correctly with the namespace and tenant ID in the path, includes the required ST-App-Key header on every request, and caches the OAuth token for up to 15 minutes before requesting a new one. When pulling Wave invoices via GraphQL, ml-connector queries for invoices created or updated after the last sync time. When a webhook arrives from Wave, it validates the HMAC-SHA256 signature against the 5 minute replay window, then posts the invoice or customer to ServiceTitan. Customer matching uses email address as the primary key; if no matching email is found in ServiceTitan, ml-connector creates a new customer record. Rate limiting on ServiceTitan is handled with exponential backoff if a 60-per-second limit is hit. Both systems support retries: Wave retries failed webhook deliveries, and ml-connector retries ServiceTitan API calls with exponential backoff.

A real-world example

A small HVAC business uses Wave Accounting to manage invoices, customers, and accounting. The dispatchers and technicians in the field use ServiceTitan to schedule jobs and see customer information on mobile. Before the integration, when a customer called about an invoice or a payment, the office staff had to look up the customer separately in Wave and ServiceTitan. With Wave and ServiceTitan connected, every time a new invoice is created in Wave, it appears in ServiceTitan attached to the correct customer so the dispatcher has billing history at hand when scheduling the next service call. Customer address changes made in Wave automatically update ServiceTitan so service teams are never sent to the wrong location.

What you can do

  • Sync Wave invoices into ServiceTitan and attach them to matching customer records by email.
  • Update ServiceTitan customer details when changes are made in Wave, including name, email, and phone.
  • Validate Wave webhook signatures to ensure only authorized invoice and customer events are processed.
  • Handle Wave OAuth token expiry and refresh automatically without manual intervention.
  • Route each ServiceTitan API call to the correct tenant using tenant ID in the URL path and the required app key header.

Questions

Which direction does data move between Wave Accounting and ServiceTitan?
The main direction is Wave into ServiceTitan. Invoices and customers created or updated in Wave flow into ServiceTitan and are attached to matching customer records. ServiceTitan invoices and jobs do not flow back to Wave.
How does ml-connector match Wave customers to ServiceTitan customers?
ml-connector uses the customer email address as the primary key. When a Wave invoice is posted to ServiceTitan, the email is matched against existing ServiceTitan customers. If no matching email is found, ml-connector creates a new customer record in ServiceTitan so the invoice can be attached.
What happens if the Wave webhook signature is invalid or expired?
ml-connector verifies the HMAC-SHA256 signature and checks that the webhook arrived within the 5 minute replay window. If the signature is invalid or the timestamp is outside the window, the webhook is rejected and not processed. This prevents replay attacks and ensures only legitimate Wave events are synced.

Related integrations

Connect Wave Accounting and ServiceTitan

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

Get started