Wave Accounting and BambooHR integration
Wave Accounting keeps the books for a small business, and BambooHR is the system of record for its people. Connecting the two removes the manual step of copying staff and pay data out of HR and into accounting. New hires, terminations, and pay changes in BambooHR show up as up-to-date vendor records in Wave Accounting, and labor cost from BambooHR compensation history posts into Wave's general ledger as journal entries. ml-connector handles the different APIs on each side and moves the data on a schedule you control.
What moves between them
The main flow runs from BambooHR into Wave Accounting. New hires and changes in BambooHR create or update matching vendor records in Wave so the contact and pay-related details stay current. Compensation history from BambooHR posts into Wave's general ledger as money transactions, with each labor cost line landing on the GL account that matches the employee's department from BambooHR job information. Because BambooHR has no finance data and Wave has no employee or payroll object, nothing financial flows back into BambooHR; Wave accounts and departments are aligned in advance so journals post to valid accounts. The cadence follows your pay calendar, with BambooHR webhooks triggering an immediate refresh of a single employee between scheduled runs.
How ml-connector handles it
ml-connector stores both credential sets encrypted and presents a Wave OAuth bearer token on each GraphQL request while resolving and caching the businessId once per business. For BambooHR it holds the company subdomain and drives OAuth against that subdomain's own token URL, since BambooHR does not share a global one. Employee, compensation, and job information are pulled with explicit fields, because a BambooHR employee call returns only the id unless each field is named, and the dated history tables are read for current pay rates rather than the flat employee record. BambooHR department and division map to Wave GL accounts so every posted journal line references an account that already exists, and each employee maps to one Wave vendor keyed by the stored BambooHR employee id. Lightweight BambooHR webhooks signal a change, then ml-connector fetches the full record before writing to Wave. Every money transaction carries a stable externalId such as a pay-period key, so a retried run never double-posts. BambooHR throttling returns 503 with a Retry-After header and Wave returns GraphQL errors inside an HTTP 200 body, so ml-connector honors the wait, checks the errors array, backs off on 429, and keeps a full audit trail with error replay.
A real-world example
A 40-person home-services company runs its books in Wave Accounting and tracks its field crews and office staff in BambooHR. Each pay period the bookkeeper exported a list of people and their pay rates from BambooHR and hand-entered the labor totals into Wave as journal entries, and kept a second spreadsheet of contractor contacts that drifted out of date whenever someone was hired or let go. With Wave Accounting and BambooHR connected, compensation from BambooHR posts into Wave's general ledger automatically against the right department account, and employee changes keep the matching Wave vendor records current. The manual re-keying and the stale contact list are both gone, and the labor accounts are ready at month end.
What you can do
- Create and update Wave Accounting vendor records from BambooHR employees, keyed by the stored BambooHR employee id.
- Post BambooHR compensation into Wave Accounting as money transactions, allocated to the GL account for each department.
- Map BambooHR department and division to Wave chart-of-accounts entries so every journal line uses a valid account.
- Bridge BambooHR OAuth on its subdomain-scoped token URL with Wave's OAuth access token and businessId.
- React to BambooHR employee webhooks with a record fetch, with retries, idempotent posting, and a full audit trail.
Questions
- Which direction does data move between Wave Accounting and BambooHR?
- The flow runs from BambooHR into Wave Accounting. Employee, compensation, and job information move from BambooHR into Wave as vendor records and general ledger journal entries. BambooHR has no vendors, invoices, or GL accounts of its own, so ml-connector does not write finance data back into BambooHR.
- How does the integration avoid posting the same payroll twice?
- Wave's moneyTransactionCreate mutation accepts a caller-supplied externalId, and ml-connector sets it to a stable value such as a pay-period key derived from the BambooHR data. If a run is retried, Wave recognizes the same externalId and the journal is not posted again. Vendor matching uses the stored BambooHR employee id for the same reason.
- Do the per-customer subdomain and Wave Pro requirement need special handling?
- Yes. BambooHR puts the company subdomain in every API and OAuth URL, including the token endpoint, so ml-connector stores that subdomain and drives auth against it rather than a shared URL. On the Wave side, third-party access requires the connected business to hold an active Wave Pro subscription, which is checked during onboarding so the failure is clear up front.
Related integrations
More Wave Accounting integrations
Other systems that connect to BambooHR
Connect Wave Accounting and BambooHR
Free to use. Add your credentials, ping your real systems, and see if we fit.
Get started