ml-connector
OdooServiceTitan

Odoo and ServiceTitan integration

Odoo runs your general ledger, purchasing, and inventory across your office. ServiceTitan runs dispatch, scheduling, and invoicing across your field-service teams. When the two are connected, new customers added in ServiceTitan appear in Odoo as partners, purchase orders created in ServiceTitan flow into Odoo as POs against the correct vendors, and invoices and payments from the field stay synchronized. This eliminates manual data re-entry between systems and keeps your accounting and operations records aligned.

How Odoo works

Odoo is an open-source enterprise resource planning suite covering accounting, purchasing, inventory, and HR. It is available as Odoo Online (SaaS), Odoo.sh (PaaS), or self-hosted. Odoo exposes partners, invoices, purchase orders, payments, GL accounts, analytic accounts, and products through XML-RPC and JSON-2 REST APIs. Authentication uses an API key paired with a username, and the API key is passed as a Bearer token in the Authorization header (JSON-2) or included in each XML-RPC call. Odoo does not have production-grade webhooks, so records are read by polling with a write_date filter and a high-water-mark timestamp.

How ServiceTitan works

ServiceTitan is a cloud-based field-service-management platform for HVAC, plumbing, electrical, and other service businesses. It exposes customers, jobs, appointments, invoices, payments, purchase orders, vendors, and inventory bills through a REST API. Authentication uses OAuth2 client credentials, and every call requires an App Key header and a Tenant ID in the URL path. ServiceTitan delivers updates via webhooks with HMAC-SHA256 signature verification, supporting event types such as customer.created, customer.updated, invoice.created, invoice.updated, job.created, and job.updated. Tokens are cached and valid for 15 minutes.

What moves between them

The main flow moves data from ServiceTitan into Odoo. When a new customer is created in ServiceTitan, ml-connector syncs it into Odoo as a partner record. Purchase orders created in ServiceTitan flow into Odoo as POs linked to the corresponding vendor. Inventory bills (AP bills) generated in ServiceTitan when a PO is marked received also flow into Odoo. Jobs and appointments are available for pull-based queries from Odoo. Invoices and payments move in both directions where Odoo needs visibility into ServiceTitan collections. The sync runs on a schedule or in real time via ServiceTitan's webhook delivery, whichever you prefer.

How ml-connector handles it

ml-connector stores the Odoo API key encrypted and presents it as a Bearer token on every JSON-2 call, or builds it into each XML-RPC payload. For ServiceTitan, it stores the OAuth2 credentials encrypted, requests a new token when the current one nears expiry (15-minute window), and extracts the App Key and Tenant ID from the configuration so they can be sent on every request. Incoming webhook payloads from ServiceTitan are validated against the HMAC-SHA256 signature before processing. Customers are mapped to Odoo partners, vendors to partner records marked as suppliers, business units to analytic accounts or cost centers, and ServiceTitan jobs to Odoo sale orders or task records. Purchase orders and inventory bills are created in Odoo under the tenant's access control rules. Because Odoo has no webhook system, polling is configured with a high-water-mark timestamp to avoid re-syncing old data. ServiceTitan's 60-call-per-second rate limit is respected, and failed calls are retried with exponential backoff. Every record carries a full audit trail.

A real-world example

A mid-sized HVAC and plumbing services company runs ServiceTitan to dispatch technicians, schedule jobs, and invoice customers from the field. They use Odoo for accounting and procurement. Before the integration, the office manager exported new customers and completed jobs from ServiceTitan daily and re-entered them into Odoo by hand, then manually matched vendor invoices from ServiceTitan POs to Odoo purchase orders at month end. With ServiceTitan and Odoo connected, customer records sync automatically when the first job is created, purchase orders flow into Odoo as soon as a dispatcher creates them, and inventory bills from received POs match to Odoo records without re-entry. Month-end AP reconciliation now takes hours instead of days.

What you can do

  • Sync ServiceTitan customers into Odoo as partner records, with contact details and business unit mapping to analytic accounts.
  • Move ServiceTitan purchase orders into Odoo as POs linked to the vendor, tracking cost per job and material allocation.
  • Flow AP inventory bills from ServiceTitan into Odoo when a PO is marked received, reconciling procurement across systems.
  • Validate ServiceTitan webhook payloads with HMAC-SHA256 signatures and respect Odoo's per-user access rules and record filtering.
  • Poll Odoo invoices and payments on demand or receive real-time updates from ServiceTitan, with full audit trails and replay on failure.

Questions

Which direction does data move between Odoo and ServiceTitan?
The main flow is ServiceTitan into Odoo. Customers, purchase orders, and inventory bills flow from ServiceTitan into Odoo. Invoices and payments can move in both directions where needed. Reference data such as vendors and business units are mapped to Odoo partners and analytic accounts.
How does ml-connector handle Odoo's API-key authentication and ServiceTitan's OAuth2?
ml-connector stores both credential sets encrypted. For Odoo, it presents the API key as a Bearer token in the Authorization header on each JSON-2 call. For ServiceTitan, it requests an OAuth2 token at startup, caches it, and requests a new one when it nears expiry. Both systems' credentials are validated before the first sync and monitored for changes.
Does Odoo's lack of webhooks mean the integration has to poll everything?
Yes, Odoo is pull-only, so ml-connector polls Odoo's invoices and payments on a schedule. ServiceTitan supports webhooks, so new customers, jobs, and POs can push to ml-connector in real time. You choose the cadence: continuous webhooks for ServiceTitan, or polling on a set schedule for Odoo data that flows back.

Related integrations

Connect Odoo and ServiceTitan

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

Get started