Xero and ServiceTitan integration
Xero runs accounting for service contractors. ServiceTitan runs the jobs, scheduling, and invoicing on the field. Connecting them keeps your accounts receivable in sync with your service invoices and your purchase records aligned between the two systems. New service jobs and invoices in ServiceTitan flow into Xero without re-keying, and vendor and customer master data stays consistent across both platforms. ml-connector handles the OAuth2 credentials, rate limits, and webhooks on each side.
What moves between them
Invoices and payments flow from ServiceTitan into Xero's Accounts Receivable. When a job is completed and invoiced in ServiceTitan, ml-connector reads the invoice and payment records from ServiceTitan and posts them as Invoices and Payments in Xero, mapped to the correct Xero account and using the customer from the ServiceTitan job. Outbound, purchase orders created in ServiceTitan flow into Xero as Purchase Orders so procurement stays synchronized. Customer master data (names, contact details) is synced bidirectionally so both systems share the single source of truth for who the customer is. ServiceTitan generates inventory bills automatically when a purchase order is marked received; these are read-only in the API and do not sync back to Xero, but ml-connector can track them for audit and reconciliation purposes.
How ml-connector handles it
ml-connector stores the OAuth2 credentials for Xero and ServiceTitan encrypted per customer and manages token refresh automatically: Xero tokens expire in 30 minutes and refresh tokens valid 60 days, while ServiceTitan tokens expire in 15 minutes. It listens for ServiceTitan webhook push events (invoice.created, invoice.updated, payment.created, customer.created) to trigger near-real-time syncs into Xero, and it polls Xero on a regular schedule using the If-Modified-Since header to detect changes made outside ServiceTitan. Because Xero enforces 5 concurrent calls and 60 per minute per tenant, ml-connector queues Xero API calls and respects those limits, backing off if it hits the rate limit. On the ServiceTitan side, the ST-App-Key header is sent with every request and the Tenant ID is verified on each call. ServiceTitan's inventory bills are read-only, so ml-connector does not attempt to update or create them; instead, it reads them to track procurement. Customers and vendors are matched by name or external ID to avoid creating duplicates. Every record carries timestamps and change tracking for full audit and replay on failure.
A real-world example
A mid-sized HVAC contractor runs ServiceTitan to manage job dispatch, technician scheduling, and on-site invoicing across three service territories. The accounting team uses Xero for accounts receivable, accounts payable, and general ledger. Before the integration, each day an accounting clerk logged into ServiceTitan, exported the previous day's completed invoices and payments, then manually re-entered them into Xero's invoice and payment modules, spending 30 to 45 minutes per day on re-keying. They also maintained a separate vendor master list for equipment suppliers, creating duplication and reconciliation errors. With ServiceTitan and Xero connected, completed invoices and payment records sync automatically to Xero the same day they are created in the field, and vendors are synced once so purchase order data is current in both systems. The accounting team now spends 5 minutes per day reviewing the sync log instead of 45 minutes re-keying, and month-end close starts with Accounts Receivable and Accounts Payable already reconciled.
What you can do
- Sync completed service invoices and customer payments from ServiceTitan into Xero's Accounts Receivable, mapped to the correct GL account and customer.
- Push purchase orders created in ServiceTitan into Xero as Purchase Orders so procurement data stays in sync.
- Keep customer and vendor master data consistent across both systems using name matching or external ID to prevent duplicates.
- Respect Xero's rate limits (5 concurrent calls, 60 per minute) and ServiceTitan's rate limits (60 calls per second) with automatic queuing and backoff.
- Listen for ServiceTitan webhook events for near-real-time sync while polling Xero on a schedule for delta updates, with full audit trail and replay on failure.
Questions
- What data moves between Xero and ServiceTitan?
- Invoices and payments flow from ServiceTitan into Xero's Accounts Receivable. Purchase orders flow from ServiceTitan into Xero's Accounts Payable. Customer and vendor master data (names, addresses, contact information) sync bidirectionally. ServiceTitan inventory bills are read-only in the API and are tracked for audit purposes but not posted back to Xero.
- How does ml-connector handle the different rate limits and token timeouts?
- ml-connector caches OAuth2 tokens after fetching them and refreshes them before expiry: Xero tokens last 30 minutes and refresh tokens are good for 60 days, while ServiceTitan tokens expire in 15 minutes. It queues API calls to Xero to respect the 5-concurrent-call limit and 60-per-minute throttle, and it respects ServiceTitan's 60-per-second rate limit. When rate limits are hit, ml-connector backs off and retries automatically.
- Why does ServiceTitan's inventory bill data not sync back to Xero?
- ServiceTitan generates inventory bills automatically when a purchase order is marked received, and the API exposes these bills as read-only. Since Xero expects bills to be created by external vendors, ml-connector tracks inventory bills for reconciliation and audit but does not attempt to post them back to Xero. Purchase orders that generate bills are tracked with full timing and status for visibility.
Related integrations
More Xero integrations
Other systems that connect to ServiceTitan
Connect Xero and ServiceTitan
Free to use. Add your credentials, ping your real systems, and see if we fit.
Get started