Odoo and Dayforce integration
Odoo runs your finance and operations. Dayforce runs your payroll and HR. Connecting the two keeps your general ledger and your headcount in agreement. Payroll journals that Dayforce produces after each pay run post directly into Odoo's GL without re-keying, mapped to the correct cost centers. Employee hires, terminations, and job changes in Dayforce reflect immediately in Odoo, so HR and finance see the same headcount.
What moves between them
The main flow runs from Dayforce into Odoo. After each payroll cycle, ml-connector polls Dayforce's payroll reports to extract the labor cost allocations by employee and organizational unit. It then posts each allocation as a line in Odoo's general ledger, mapped to the GL account and cost center that correspond to that employee's org unit and job classification. Employee records flow the same direction: hires, terminations, and job changes in Dayforce update Odoo's hr.employee records so the two systems reflect the same workforce. GL accounts and cost centers are treated as reference data and aligned before any payroll journals are posted.
How ml-connector handles it
ml-connector stores the Dayforce OAuth credentials and Odoo API key encrypted and refreshes the Dayforce Bearer token every hour or when a call returns 401 Unauthorized. For Odoo, it uses the JSON-2 API and includes the API key as a Bearer token. It polls Dayforce's employee and payroll endpoints with filterUpdateDateRangeMin and filterUpdateDateRangeMax parameters tied to your payroll calendar, and polls Odoo to validate that GL accounts and cost centers exist before posting. The mapping step ensures every payroll line references an Odoo GL account and cost center that matches the Dayforce org unit and job code; unmapped records are held and retried after a new mapping is provided. Dayforce tokens expire after one hour, so ml-connector proactively refreshes before expiry. The Dayforce client-specific URL is cached but refreshed daily via the ClientMetadata endpoint to minimize redirect overhead. Every payroll posting and employee update carries a timestamp and audit trail, so records can be replayed if a downstream Odoo validation fails.
A real-world example
A mid-sized professional services firm runs Odoo for project accounting and cost center allocation, and uses Dayforce for payroll across multiple offices and departments. Before the integration, the accounting team manually exported payroll summaries from Dayforce after each pay run, matched employees to their org units and assignments, and hand-entered the labor cost lines into Odoo's GL, split by cost center. The process took two to three hours per payroll and often produced rounding differences or missed allocations. After connecting Odoo and Dayforce, payroll GL entries post automatically after each cycle, assigned to the correct office and project cost centers, and employee changes in Dayforce are reflected in Odoo's org chart and job titles immediately. The accounting team reclaims the payroll entry time and month-end close starts with the labor accounts already reconciled.
What you can do
- Post Dayforce payroll cost allocations into Odoo's general ledger after every pay cycle, mapped to the correct GL accounts and cost centers.
- Keep Odoo employee records in sync with Dayforce hires, terminations, and job changes so HR and finance see the same headcount.
- Map Dayforce organizational units and job codes to Odoo cost centers and GL dimensions so payroll allocations land on valid accounts.
- Authenticate Dayforce with hourly OAuth 2.0 token refresh and Odoo with API key bearer tokens, and cache the client-specific Dayforce URL to minimize redirects.
- Poll on a schedule tied to your payroll calendar, with retries and a full audit trail on every record so failed entries can be replayed.
Questions
- Which direction does data move between Odoo and Dayforce?
- The main flow is Dayforce into Odoo. Payroll cost allocations and employee records move from Dayforce into Odoo's general ledger and hr.employee module. GL accounts and cost centers are aligned in both directions so payroll lines reference valid Odoo dimensions. Odoo general ledger entries are read-only from Dayforce's perspective, so ml-connector does not write financial entries back into Dayforce.
- How does the integration handle Dayforce's hourly token expiry?
- ml-connector refreshes the Dayforce OAuth Bearer token proactively every hour, before expiry, so payroll polling never encounters an expired token. If a call does return 401 Unauthorized, the token is refreshed immediately and the call is retried. The client-specific API URL is also refreshed daily via the ClientMetadata endpoint to avoid accumulating redirects.
- What happens if a payroll allocation references an unmapped cost center or GL account in Odoo?
- ml-connector validates GL accounts and cost centers against Odoo before posting any payroll line. If a mapping is missing, the record is held with an audit trail and retried after the mapping is provided. This prevents partial postings and ensures every payroll entry lands on a valid account and cost center from the first attempt.
Related integrations
More Odoo integrations
Other systems that connect to Dayforce
Connect Odoo and Dayforce
Free to use. Add your credentials, ping your real systems, and see if we fit.
Get started