ml-connector
Epicor KineticBILL

Epicor Kinetic and BILL integration

Epicor Kinetic runs manufacturing, distribution, procurement, and finance. BILL runs accounts payable, handling vendor payments and approvals. Connecting the two means approved AP invoices and their vendors move from Epicor Kinetic into BILL so they can be paid, and the payment status BILL produces flows back so the Epicor ledger reflects what was actually paid. ml-connector handles the different APIs and auth models on each side and moves the data on a schedule you control. Purchase orders stay in Epicor Kinetic, since BILL has no purchase order object.

How Epicor Kinetic works

Epicor Kinetic exposes vendors, AP invoices, purchase orders, AP payments, GL accounts, customers, and parts through REST business object services that are OData v4 compliant, browsable in the Swagger help built into each instance. The v2 API runs against a tenant-specific URL with a mandatory Company segment, so there is no shared hostname, and it authenticates with Basic auth plus an API key, OAuth2 client credentials plus an API key on cloud, or a short-lived token from TokenResource.svc. Epicor Kinetic has no native outbound webhooks, so records are read by polling an OData date filter such as UpdatedOn, paging with $top and $skip.

How BILL works

BILL exposes vendors, bills, payments, recurring bills, vendor credits, a chart of accounts, and classification dimensions through its v3 REST API at gateway.prod.bill.com. It authenticates with a session token: a login call sends a developer key plus org email, password, and organization ID and returns a sessionId carried on later calls, which expires after about 35 minutes of inactivity. BILL pushes vendor, bill, and payment events by webhook signed with HMAC-SHA256 in the x-bill-sha-signature header, holds at most ten subscriptions per org, and disables a subscription after repeated delivery failure. BILL has no purchase order object.

What moves between them

The main flow runs from Epicor Kinetic into BILL. ml-connector reads approved AP invoices and their vendor records from Epicor Kinetic and creates them as bills and payees in BILL, mapping each invoice line to the matching BILL chart-of-accounts entry. Payment activity flows the other direction: as BILL records or updates a payment, ml-connector reads it and posts the payment status against the originating Epicor invoice. Vendor records are kept aligned so a bill in BILL always points at a known payee. Purchase orders are not synced, since BILL has no purchase order object, so they remain in Epicor Kinetic.

How ml-connector handles it

ml-connector stores both credential sets encrypted. On the Epicor side it accepts the full tenant URL and Company segment per customer, signs each request with Basic auth or an OAuth2 bearer token, and always sends the API key header, since Kinetic rejects calls without it even when the token is valid. On the BILL side it performs the login call to obtain a sessionId and re-logs in and retries when a call returns an auth error, because BILL reports an expired session as a generic 401 rather than a clear code. Because Epicor Kinetic is poll-only, ml-connector polls AP invoices and vendors on a schedule using an OData date filter and $top and $skip paging. BILL payment status is taken from a payment webhook where it is enabled, with a scheduled poll as backup since a BILL subscription disables itself after repeated failures. Vendors are mapped first so every bill references an existing payee, and GL accounts are matched so each line lands on a valid account. Neither system supports an idempotency key, so ml-connector dedupes on invoice number plus vendor in Epicor and on BILL entity IDs, and keeps in-flight calls within BILL's limit of three concurrent requests per org. Every record carries a full audit trail and can be replayed if a downstream call fails.

A real-world example

A mid-sized contract manufacturer with about 300 staff runs Epicor Kinetic for production, procurement, and finance, and uses BILL to pay its suppliers. Before the integration, an AP clerk exported approved invoices from Epicor each week and re-keyed them into BILL as bills, then later copied payment dates and amounts back into Epicor by hand. Invoices sometimes sat unpaid past their due date, vendors were duplicated in BILL, and the cash position in Epicor lagged what had actually cleared. With Epicor Kinetic and BILL connected, approved invoices and their vendors land in BILL within the polling window, and payment status posts back against the right Epicor invoice automatically. Bills get paid on time and the ledger matches what BILL actually paid.

What you can do

  • Push approved Epicor Kinetic AP invoices into BILL as bills so they can be paid.
  • Keep BILL payees aligned with Epicor Kinetic vendor records so every bill points at a known supplier.
  • Read BILL payment status back and post it against the originating Epicor Kinetic invoice.
  • Bridge Epicor tenant login plus API key to BILL's session token, refreshing the session on expiry.
  • Poll Epicor on a schedule with invoice-number and entity-ID dedup, retries, and a full audit trail on every record.

Questions

Which direction does data move between Epicor Kinetic and BILL?
The main flow is Epicor Kinetic into BILL. Approved AP invoices and their vendor records move from Epicor into BILL so they can be paid. Payment status flows the other way, from BILL back to Epicor, so the originating invoice shows what was paid. Purchase orders are not synced because BILL has no purchase order object, so they stay in Epicor Kinetic.
How does the integration bridge the two different auth models?
Epicor Kinetic uses Basic auth or an OAuth2 bearer token plus a required API key against a tenant-specific URL, while BILL uses a session token obtained from a login call with a developer key and org credentials. ml-connector stores both credential sets encrypted, always sends the Epicor API key since Kinetic rejects calls without it, and re-logs in to BILL when a session expires, since BILL reports expiry as a generic 401.
Does BILL push payment updates, or does ml-connector poll for them?
Both are supported. Where a BILL payment webhook is enabled, ml-connector verifies its HMAC-SHA256 signature and uses it to trigger the status update. A scheduled poll runs as backup, because a BILL subscription disables itself after repeated delivery failures. On the Epicor side everything is polled, since Epicor Kinetic has no native webhooks.

Related integrations

Connect Epicor Kinetic and BILL

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

Get started