ml-connector
Sage X3Dayforce

Sage X3 and Dayforce integration

Sage X3 runs finance, procurement, and inventory for mid-market manufacturing and distribution. Dayforce runs payroll and HR across the organization. Connecting the two keeps your general ledger labor accounts current after every payroll run and ensures headcount in X3 reflects hires, terminations, and status changes in Dayforce. Before the integration, finance teams export payroll summaries from Dayforce and manually re-key labor totals into X3; now the GL posting happens automatically, and the month-end close starts with labor accounts already reconciled.

How Sage X3 works

Sage X3 exposes GL accounts, GL entries, suppliers, customers, purchase orders, sales invoices, and inventory items through REST (api1) or GraphQL (Xtrem) APIs. Authentication uses OAuth2 client credentials (JWT bearer) on the GraphQL path or HTTP Basic Authentication on the legacy REST api1 endpoint. X3 has no native webhooks or outbound event notifications, so all data retrieval is poll-based using updatedDate and modifiedDateTime fields to detect changes since the last sync. The server URL, port, and X3 folder name are customer-specific with no shared base URL. Access tokens expire in 5 minutes; refresh tokens remain valid for 30 days. Basic auth on REST api1 must be explicitly enabled by the customer administrator in nodelocal.js.

How Dayforce works

Dayforce exposes employees, organizational units, jobs, positions, payroll summaries, and balance period reports through REST endpoints over HTTPS. Authentication uses OAuth2 Resource Owner Password Credentials with a username, password, and client credentials, returning a JWT bearer token that expires in 1 hour. The client-specific base URL must be retrieved via the ClientMetadata endpoint and refreshed at least once per day to avoid redirect overhead. Dayforce has no native vendor, invoice, purchase order, or accounts-payable modules and no outbound webhooks; all integration is poll-only with delta detection using filterUpdateDateRangeMin and filterUpdateDateRangeMax parameters. GL account codes are configured inside Dayforce and appear on payroll reports but have no standalone endpoint.

What moves between them

The main flow is Dayforce into Sage X3. After each payroll cycle, ml-connector reads payroll journals and employee records from Dayforce, maps the payroll GL amounts to X3 GL accounts by cost center and department, and posts the labor cost allocations into X3's general ledger. Employee records from Dayforce (hires, terminations, status changes) are also written to X3 so headcount remains aligned. Cost center and department reference data is synchronized in both directions so payroll allocations land on valid X3 dimensions. GL entries posted to X3 are write-only from Dayforce; ml-connector does not write financial data back to Dayforce payroll records.

How ml-connector handles it

ml-connector stores Dayforce and Sage X3 credentials encrypted and manages two separate token lifecycles. Dayforce tokens expire in 1 hour and are refreshed before each poll cycle; X3 bearer tokens expire in 5 minutes but have a 30-day refresh token window, so ml-connector monitors both expiry windows and proactively refreshes. The Dayforce client-specific URL is fetched from ClientMetadata on first connect and refreshed daily. Sage X3 requires either GraphQL (Xtrem) for X3 V12+ or REST api1 for V6+; ml-connector uses the GraphQL path by default if available. Both systems are poll-only, so ml-connector polls on a cadence tied to your payroll calendar (typically bi-weekly or monthly after payroll processing completes). Cost centers and departments are mapped first so every GL journal line lands on a valid X3 account and cost center. Changes are detected using Dayforce's filterUpdateDateRange parameters and Sage X3's updatedDate fields to avoid re-processing the same records. Every record carries a full audit trail and can be replayed if a GL posting fails.

A real-world example

A mid-sized food and beverage distributor runs Sage X3 for procurement, inventory, and finance across three regional warehouses and a head office, and uses Dayforce for payroll and HR across all locations. Before the integration, after every bi-weekly payroll run the accounting team extracted payroll registers from Dayforce and re-entered labor cost totals into X3 by hand, manually assigning them to warehouse cost centers. Month-end close required a full headcount audit to reconcile HR records with X3 GL balances. With Sage X3 and Dayforce connected, each payroll cycle flows directly into X3's GL, allocated to the correct warehouse and department, and employee changes keep the two systems aligned. Month-end close starts with labor accounts already reconciled and matching Dayforce records, eliminating the manual re-keying and headcount audit steps.

What you can do

  • Post Dayforce payroll GL journals into Sage X3's general ledger after each pay cycle, allocated to the correct cost centers and departments.
  • Keep Sage X3 headcount aligned with Dayforce hires, terminations, and rehires across all regions.
  • Map Dayforce cost center, department, and job code data to Sage X3 GL dimensions so payroll allocations land on valid accounts.
  • Manage Dayforce bearer token refresh (1-hour expiry) and Sage X3 bearer and refresh token lifecycle (5-minute and 30-day windows) transparently.
  • Poll both systems on a payroll-aligned schedule with delta detection and a full audit trail for every GL entry and employee record.

Questions

Which direction does data move between Sage X3 and Dayforce?
The main flow is Dayforce into Sage X3. Payroll GL journals and employee records move from Dayforce into X3, while cost centers and departments are aligned in both directions. GL entries posted to X3 are read-only from Dayforce, so ml-connector does not write financial data back to Dayforce.
How does ml-connector handle the different token expiry windows between Dayforce and Sage X3?
Dayforce tokens expire in 1 hour and are refreshed before each poll cycle. Sage X3 bearer tokens expire in 5 minutes but have a 30-day refresh token window, so ml-connector monitors both windows and proactively refreshes each before expiry. This prevents authentication failures mid-sync and avoids outages from unexpected token loss.
Why does Sage X3 require a customer-specific server URL and Dayforce require a daily ClientMetadata fetch?
Sage X3 is on-premise and cloud with no shared base URL, so each customer instance publishes its own hostname and port. Dayforce is multi-tenant SaaS but assigns each customer an optimized API endpoint that must be retrieved via ClientMetadata and refreshed daily to minimize redirect overhead and network latency.

Related integrations

Connect Sage X3 and Dayforce

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

Get started