Xero and BambooHR integration
Xero runs accounting for small and mid-sized businesses. BambooHR is the system of record for people: who is employed, in which department, at what pay. Connecting the two keeps your accounting records in step with HR without re-keying. New hires, terminations, and department moves in BambooHR flow into Xero, where employees become contacts and Payroll records and departments become tracking categories you can tag costs against. ml-connector handles the very different APIs on each side and moves the data on the cadence you set.
What moves between them
The flow runs from BambooHR into Xero. ml-connector reads BambooHR employees and their job and employment status tables and writes them into Xero as contacts and, where a regional Payroll API is in use, as Payroll employees, carrying first name, last name, work email, hire date, and active or terminated status. BambooHR departments and divisions are created as Xero tracking categories and options so labor and expense lines can be tagged to the right dimension. BambooHR remains the people source of record, so ml-connector does not write employee changes back from Xero. The sync runs on a schedule and also fires when a BambooHR change event arrives.
How ml-connector handles it
ml-connector stores both credential sets encrypted and bridges two unlike auth models. BambooHR token endpoints are scoped to each customer subdomain, so the connector keeps a per-customer companyDomain rather than a single global token URL, and it refreshes the one-hour BambooHR access token and the 30-minute Xero access token before each expires. On the Xero side it attaches the Xero-tenant-id header to target the right organization. Because BambooHR webhooks are metadata only, the connector receives an employee.updated event with its changedFields list, verifies the HMAC-SHA256 signature over the raw body plus timestamp, then calls GET on that employee to read current values, since BambooHR returns only the id unless fields are named explicitly. Departments map to Xero tracking categories first, and Xero caps active categories at two, so the connector validates that limit before creating options. BambooHR has no idempotency header, so a stored BambooHR employee id anchors each contact and a 409 on duplicate email is treated as an existing record rather than an error. A scheduled If-Modified-Since poll backfills any event missed during an outage, and every record carries a full audit trail with retries and replay.
A real-world example
A 180-person professional services firm runs Xero for its books and BambooHR for HR across three offices. Before the integration, every new hire was entered twice, once in BambooHR and again as a Xero contact and Payroll record, and finance tagged time and expenses to departments by hand from a spreadsheet HR updated each month. Terminated staff sometimes lingered as active Payroll records past their last day. With Xero and BambooHR connected, a new hire in BambooHR appears in Xero within minutes, the department lands as a tracking category, and a termination flips the Xero record to inactive on the spot. The double entry and the stale-headcount cleanup at month-end are gone.
What you can do
- Create and update Xero contacts and Payroll employees from BambooHR employee records as people are hired, changed, or terminated.
- Build Xero tracking categories and options from BambooHR departments and divisions so labor and expense lines carry the right dimension.
- Carry first name, last name, work email, hire date, and active or terminated status from BambooHR into Xero.
- Bridge BambooHR per-subdomain OAuth and Xero tenant authentication, refreshing both short-lived tokens automatically.
- Sync on BambooHR employee change events and backfill missed changes with a scheduled If-Modified-Since poll, with retries and a full audit trail.
Questions
- Which direction does data move between Xero and BambooHR?
- The flow runs from BambooHR into Xero. Employee records, departments, and employment status move from BambooHR into Xero as contacts, tracking categories, and Payroll records. BambooHR is the people system of record, so ml-connector does not write employee changes back from Xero into BambooHR.
- Can BambooHR send accounting data like invoices or GL accounts to Xero?
- No. BambooHR is an HRIS and has no vendors, invoices, purchase orders, or GL accounts. Its value in this pairing is people data: employees, departments, compensation, and employment status, which ml-connector turns into Xero contacts, Payroll employees, and tracking categories for tagging costs.
- How does the integration deal with the per-company subdomain and lightweight webhooks in BambooHR?
- BambooHR token and API URLs are scoped to each customer subdomain, so ml-connector stores a per-customer companyDomain instead of one shared endpoint. Its webhooks carry only a changed-fields list, so the connector verifies the HMAC-SHA256 signature, then calls GET on the named employee to read the current values, since BambooHR returns only the id unless fields are requested explicitly.
Related integrations
More Xero integrations
Other systems that connect to BambooHR
Connect Xero and BambooHR
Free to use. Add your credentials, ping your real systems, and see if we fit.
Get started