Epicor API Guide: REST API Documentation for Kinetic 

Table of Content
  1. No sections available

Search

Code samples are illustrative. Endpoint paths follow Epicor's REST v2 conventions; method parameter names can differ by Kinetic release, so confirm each against your instance's REST help page before publishing any change to them. 

Open Kinetic in a browser, press F12 and enter an AP invoice by hand. The Network tab fills with REST calls, because the Kinetic web client talks to the server through the same services an external integration uses. Epicor says its Open REST API is built on the service architecture that powers Kinetic itself, and community developers routinely trace those UI calls to learn the exact sequence a screen follows. 

That makes the Epicor API the most direct way to read and write Kinetic data from your own code. It is also where most first integrations stall: an API key with no access scope, a BAQ URL that is case sensitive, or an AP invoice that saves but never posts. Our Epicor integration guide compares REST with Service Connect, EDI and iPaaS. This guide goes one level down, into the endpoints, headers and call sequences developers need. 

You will learn where Kinetic's REST API documentation lives, how to authenticate, how to read business objects and BAQs, and how a finance AI system writes AP invoices and GL journals back without creating duplicates. 

What the Epicor Kinetic REST API Exposes 

The Epicor REST API is a set of HTTPS services over Kinetic's business logic, returning JSON and following the OData v4 conventions for querying. Epicor states that business objects, processes, reports, BAQs and Epicor Functions are all reachable through REST, with API keys and access scopes controlling which services each integration can call. 

REST v1 vs v2 

There are two versions on most instances. An Epicor developer explained on EpiUsers that v2 arrived in release 10.2.400 to adopt the OData 4 spec and simplify company handling and access scopes. The practical differences: 

  • URL root. v1 used /api/v1/; v2 uses /api/v2/odata/{Company}/, so the company is part of every request. 


  • API keys. v2 requires an API key on every call, in addition to a user identity. 


  • BAQ format. v2 BAQ reads end in /Data, which made them readable by Excel and Power BI OData clients. 

Build new integrations on v2. Keep v1 only for legacy code you have not yet migrated. 

The four service types you will call 



Service type 



URL pattern (v2) 



Typical use 



Business objects (BOs) 



/api/v2/odata/{Company}/Erp.BO.APInvoiceSvc/... 



Read and write records such as suppliers, POs, AP invoices and journals, with Epicor's validations 



Business Activity Queries (BAQs) 



/api/v2/odata/{Company}/BaqSvc/{BaqID}/Data 



Read a saved, joined query as a feed 



Epicor Functions (EFx) 



/api/v2/efx/{Company}/{Library}/{Function} 



Call server-side logic you wrote and published in Kinetic 



Processes and reports 



Under the matching Ice or Erp service 



Submit reports or long-running processes 

Business objects come in two flavors. OData entity endpoints such as /Vendors support GET, POST and PATCH. Custom methods such as GetNewAPInvHedInvoice or UpdateMaster are called with POST and mirror what a Kinetic screen does, step by step. Finance write-backs almost always use the custom methods. 

Where to Find Epicor API Documentation for Your Instance 

Epicor does not publish one global API reference. Each Kinetic instance documents itself, so the most accurate Epicor API documentation is the one generated by your own server, for your own release and customizations. 


Source 

Where it lives 

What it gives you 

REST help (Swagger) 

https://{server}/{instance}/api/help/v2/ 

Every BO, BAQ and Function service, with schemas and a "try it" console 

REST help app 

https://{server}/{instance}/apps/resthelp/#/home on newer releases (EpiUsers) 

The same catalog, plus generated sample requests 

OData metadata 

.../Erp.BO.CustomerSvc/$metadata 

Machine-readable entity and field definitions for code generation  

Functions OpenAPI 

.../api/swagger/v2/efx/{Library}/{Company}.json 

The signature of each published Epicor Function  

REST Services Guide 

Kinetic's built-in help, under Troubleshooting & Security 

Epicor's own guide to authentication and data security  

Browser developer tools 

F12 > Network while using a Kinetic screen 

The exact methods, order and payloads a screen sends 

The REST help is good at telling you which fields exist and weak at telling you which are required. For finance objects with many child tables, the browser trace is usually the faster route: run the transaction once by hand, record the calls, then reproduce them in code. Base URLs differ between cloud and on-premises deployments, which is why an Epicor API URL should always be copied from the instance rather than assumed. 

How to Access the Epicor REST API: Keys, Scopes and Tokens 

Every v2 request carries two credentials: an API key that decides which services the caller may reach, and a user identity that decides which data and companies it may see. Setting up Epicor API access takes five steps.

  1. Create a dedicated integration user. Use a service account, not a person's login, so permissions and audit history belong to the integration. Community admins report that assigning an access scope marks the account as an integration account. 


  2. Define an access scope. In Access Scope Maintenance, list only the services, methods and BAQs the integration needs. Scopes can be narrowed to individual methods, so a reporting key can be read-only. 


  3. Generate the API key. In API Key Maintenance, create a key and attach the scope. Copy it into a secrets vault when it is created. 


  4. Choose how the user authenticates. Basic authentication works everywhere. For repeated calls, request a bearer token by POSTing to TokenResource.svc, which returns an access token and its lifetime in seconds. Cloud tenants can also use Epicor IdP or Microsoft Entra ID. 


  5. Send both on every call. Put the key in the x-api-key header. The query-string form ?api-key= works, but URLs are often logged, so keep keys in headers.  

Two details save debugging time. TokenResource.svc issues no refresh token, so request a new one before expiry; the lifetime is set in the Epicor Admin Console. And a token without a SessionInfo header opens a new Epicor session on each request, so long-running jobs should log in once, reuse the session ID and log out when done. 

Reading Kinetic Data: OData Queries and BAQ Endpoints 

Use business object endpoints when you need one entity with Epicor's field names, and BAQs when you need a join that Kinetic users already maintain. Both accept standard OData options such as $select, $filter, $top and $skip. 

Querying business objects 

The URL names the company, the service and the entity set. This request pulls open purchase orders for one supplier, with only the fields an invoice-matching step needs: 

GET /{instance}/api/v2/odata/{Company}/Erp.BO.POSvc/POes?$select=PONum,VendorNum,OrderDate,OpenOrder&$filter=VendorNum eq 1042 and OpenOrder eq true&$top=100 
x-api-key: {key} 
Authorization: Bearer {token} 

Check the entity set name in the service's $metadata before coding: Epicor pluralizes some names unusually, as POes shows. 

Calling a BAQ 

An Epicor BAQ REST API call runs a saved query and returns its rows. Parameters go in the query string: 

import os, requests 
 
BASE = "https://{server}/{instance}/api/v2/odata/{Company}" 
s = requests.Session() 
s.headers.update({ 
   "x-api-key": os.environ["EPICOR_API_KEY"], 
   "Authorization": f"Bearer {os.environ['EPICOR_TOKEN']}", 
   "Accept": "application/json", 
}) 
 
# A BAQ listing PO receipts not yet invoiced, filtered by fiscal period 
r = s.get(f"{BASE}/BaqSvc/HB-UninvoicedReceipts/Data", 
         params={"FiscalPeriod": "10", "$top": 500, "$skip": 0}) 
r.raise_for_status() 
rows = r.json()["value"] 

Three BAQ habits prevent most support tickets. The /Data segment is case sensitive (EpiUsers). The BAQ must be inside the key's access scope, or it will not appear. And page explicitly with $top and $skip rather than relying on server defaults. Updatable BAQs also accept writes: GET .../GetNew returns a blank row and PATCH .../Data saves one. 

A query like the one above is how month-end accrual automation finds receipts without invoices. The same pattern feeds reporting through the Epicor REST API without direct database access, which Epicor's cloud does not allow. 

Reading only what changed 

Full reloads of supplier or PO tables slow down production and waste licenses. Store a high-water mark per entity, such as a last-changed date or a row-version column where the table exposes one, and filter on it each run. Paging plus incremental filters keep a sync job's footprint small even on tenants with thousands of open POs. 

Writing AP Invoices and GL Journals Back Through the Epicor API 

Writes should go through business object methods, in the same order a Kinetic screen calls them. That way Epicor's own defaulting, validation, period checks and security still run, and nothing lands that a clerk could not have entered. Forum threads on AP invoices and GL journals show that posting raw entity rows with POST often fails or leaves child records, such as GL distributions, incomplete. 

Every method call has the same shape: POST to the method, send the working dataset ds plus any parameters, and carry the returned ds into the next call. 


def call(service: str, method: str, body: dict) -> dict: 
   """POST to a business object custom method and return its JSON.""" 
   url = f"{BASE}/Erp.BO.{service}/{method}" 
   r = s.post(url, json=body, timeout=60) 
   if r.status_code >= 400: 
       # Kinetic returns a JSON body with ErrorMessage; surface it as-is 
       raise EpicorError(r.status_code, r.json().get("ErrorMessage")) 
   return r.json() 
 
# Each step takes the dataset returned by the step before it 
res = call("APInvoiceSvc", "GetNewAPInvHedInvoice", {"ds": ds, "cGroupID": group_id}) 
ds = res["parameters"]["ds"] 

Parameter names such as cGroupID vary by method and release, so take them from your REST help page or a browser trace rather than from this example. 

The AP invoice write sequence 

In Epicor Kinetic accounts payable, invoices live inside an invoice group. A typical sequence, reconstructed from community traces, is: 

  1. Create or select the group in Erp.BO.APInvGrpSvc. 


  2. Get a new header with APInvoiceSvc/GetNewAPInvHedInvoice, which returns a template with Epicor's defaults. 


  3. Fill and save the header (supplier, invoice number, dates, amounts) and save it with UpdateMaster. 


  4. Add lines. Receipt-matched lines for PO invoices, miscellaneous lines for non-PO spend, each followed by UpdateMaster. Developers report that GL distribution rows are easiest to set through UpdateMaster as the UI does, rather than through the APInvExpTGLCs entity set. 


  5. Attach the source document so auditors can open the original PDF from the invoice. 


  6. Post the group using the method your release's Post action calls, then release the group with APInvGrpSvc/UnlockGroup. Without that step the service account can hold the group locked for other users. 

The GL journal write sequence 

An Epicor GL journal entry follows the same group, header, lines pattern: 


Step 

Service 

Methods 

1. Journal group 

Erp.BO.GLJrnGrpSvc 

GetNewGLJrnGrp, then Update 

2. Journal header 

Erp.BO.GLJournalEntrySvc 

GetNewGlJrnHedTran, PreUpdate, Update 

3. Journal lines 

Erp.BO.GLJournalEntrySvc 

GetNewGLJrnDtlMnl, then Update per line 

4. Post 

Method behind the Post Entry action 

Trace it in your release 

The header carries book, fiscal year and period, so Epicor's own period checks reject a closed or invalid period with a readable error instead of letting it through. Posting is reachable from REST, since the Kinetic browser client posts through REST too. 

When to wrap the sequence in an Epicor Function 

Many experienced Kinetic developers advise moving multi-step writes into an Epicor Function and calling that one endpoint from outside. An Epicor Functions REST API call runs the whole sequence server-side in one request, can be added to an access scope, and hides UI-level quirks. The trade-off is ownership: the logic now lives in Kinetic, must be published per environment, and needs retesting after upgrades. External orchestration keeps logic in your codebase and versioned with it. Choose based on who will maintain it. 

Production Patterns for Epicor Kinetic REST Integrations 

A write that works once in Swagger is a prototype. A write that survives retries, timeouts, closed periods and Kinetic upgrades is an integration. These are the patterns that separate the two, and the controls a dependable ERP integration layer has to provide. 


Risk 

Pattern 

How it looks against Kinetic 

Duplicate vouchers after a retry 

Idempotent writes with a deterministic key 

Key each invoice on supplier plus invoice number. Query APInvoiceSvc for that pair before creating; update an unposted match, stop and flag a posted one 

"Saved" is not "posted" 

Read-back verification 

After each write, re-read the record and compare amount, currency, company, period and status before reporting success 

Retrying errors that will never succeed 

Classify failures 

Retry timeouts and 5xx responses without a body using exponential backoff; send 4xx business errors (closed period, inactive GL account) to a person 

Half-built records 

Compensating rollback 

If a line or post step fails, delete the header or group the run created, so the next attempt starts clean 

Locked groups and stray sessions 

Clean session handling 

Call UnlockGroup after posting; log out sessions opened with SessionInfo 

Over-privileged keys 

Least privilege 

One key and scope per integration, stored in a vault, rotated on a schedule 

Breakage after an update 

Regression tests 

Replay known "golden" invoices and journals in a test company before each Kinetic update 

Failures nobody sees 

Alerting and audit links 

Log each source document ID beside the Epicor record ID; alert in Slack or Teams 

Microsoft's retry pattern guidance puts the order plainly: confirm an operation is idempotent before you retry it. In AP, a missed idempotency check is a duplicate payment waiting to happen, so pair the key with content-based duplicate invoice detection on amount, date and lines. 

Mapping is the other long-term cost. Kinetic tenants add user-defined fields, GL segment rules and company-specific tax codes, and hard-coding them turns every change into a deploy. Template-driven mapping, like the approach in Hyperbots' data model designer, keeps those differences in configuration. 

Finally, build for the cloud even if you run on-premises today. With Epicor's final on-premises Kinetic feature release tentatively planned for January 2028, REST integrations will move to Kinetic cloud with new URLs and credentials, while direct database writes will not move at all. 

How Hyperbots Writes AP Invoices and GL Entries to Kinetic: Connector Design and Persimmon Case Study 

Hyperbots is an agentic AI platform for finance and accounting that sits beside Epicor Kinetic and leaves Kinetic as the system of record, the model described in how AI complements ERP systems. Its HyperAGENTS read master data and transactions from Kinetic, do the document and decision work, then write approved results back through the same REST services covered above. 

How the connector applies these patterns 

The Hyperbots Epicor connector is a working example of each production pattern in this guide. 

Pattern from this guide 

How the Hyperbots connector implements it 

Authenticate per v2 rules 

A Kinetic token plus the tenant's API key; OData for reads and change tracking, business object methods for writes 

Write the way the screen does 

The Invoice Processing HyperAGENT creates the AP invoice group, header and lines, codes non-PO lines to GL, and matches PO lines to receipts with AI three-way matching 

Idempotent writes 

Group IDs derive from supplier and invoice number, so a correction replaces rather than duplicates 

Compensating rollback 

If any step fails, the connector removes what that run created 

Posted means posted 

Posting runs Epicor's pre-post checks and reports success only once Epicor confirms the invoice is posted 

GL write-back 

Month-end accrual journals are booked and then reversed when the invoice arrives 

Incremental reads 

Reads track Epicor's row-revision number and are paged to protect production 

Actionable errors 

Epicor's own error text appears in Hyperbots; failures alert in Slack or Teams 

Configurable mapping 

Field mappings are templates, so custom fields are configuration, not code 


Anything outside tolerance goes to a reviewer through human-in-the-loop controls, while Epicor keeps its posting rules, periods and security. Because the connector already exists, Hyperbots integrations with Epicor typically take 6 to 8 weeks, the onboarding model behind its plug-and-play ERP adapters. 

Teams building their own Kinetic pipeline can use the extraction layer on its own. HyperAPI, Hyperbots' developer-facing API for finance documents, turns invoices and other finance documents into validated JSON, with Python, Node.js and REST access, ready to feed the AP write sequence above. 

Case study: Persimmon Technology on on-premises Epicor 

In the Persimmon Technology interview, Dave Sackett, VP of Finance, describes how the integration runs against on-premises Epicor: 

  • Connectivity. A lightweight agent on the Epicor app server opens an outbound HTTPS tunnel to Hyperbots, so no inbound firewall changes were needed. It calls Epicor REST v2 locally, or Service Connect on older builds. 


  • Sync cadence. Chart of accounts and company-site structures sync weekly; suppliers, parts and GL codes daily; PO receipts and supplier invoices hourly. Writes of POs, invoices, journal entries and accruals happen in real time. 


  • Write controls. Every write is read back immediately. Errors such as closed fiscal periods or duplicate document numbers get three automatic retries, then land in an integration exceptions queue with a Teams alert. 


  • Security. The platform is SOC 2 Type II compliant and ISO 27001 certified, and access keys inherit Epicor's security groups with least-privileged access. 


  • Results. About 80% of invoices flow straight through, from PDFs in the AP mailbox to posted AP invoices in Epicor, and Persimmon cut AP data entry by 80%. 


  • Timeline. The rollout took 3 to 5 weeks with no custom code, faster than the 6 to 8 weeks that is typical for Hyperbots on an ERP with an existing connector. 

Taking Your Epicor Kinetic REST API Integration to Production 

The Epicor API gives developers the same services Kinetic's own screens use. Your instance's REST help is the documentation of record, v2 with a scoped API key is the access model, OData and BAQs cover reads, and business object methods called in screen order cover writes. 

The harder engineering sits around those calls. Finance write-backs need idempotent keys, read-back checks, classified errors, clean rollbacks and regression tests, because an AP invoice that posts twice or never posts costs more than one that fails loudly. Build those controls yourself, or start from a connector that already has them. 

See how Hyperbots HyperAGENTS read from and write back to Epicor Kinetic using your own invoices and journals. Request a demo. 

Frequently Asked Questions About the Epicor API 

Q1. Why does my Epicor REST call return "Rest calls must pass a valid API Key" or a 401? 

The first message means the v2 endpoint received no usable API key, usually because it was missing from the x-api-key header or the key is not linked to an access scope. A 401 means the user identity failed, so check the Basic credentials or whether the bearer token has expired. A 403-style denial on one service with others working usually means that service or BAQ is not in the key's scope. Also confirm you are calling /api/v2/odata/{Company}/ rather than a v1 path. 

Q2. Should I use Basic authentication or bearer tokens with the Epicor Kinetic API? 

Both work with an API key. Basic sends credentials on every request, which is simple but widens exposure if anything logs headers. Bearer tokens from TokenResource.svc limit how often the password travels, but have a fixed lifetime and no refresh token, so your client must request a new one before expiry. Cloud tenants can use Epicor IdP or Microsoft Entra ID instead, which keeps passwords out of the integration entirely. 

Q3. Can I post an AP invoice through the Epicor REST API, or only create it? 

You can do both. The Kinetic browser client posts through REST, so any posting action available on screen has a REST method behind it. Trace the Post action in your release with browser developer tools, call the same method, then re-read the invoice to confirm it shows as posted. Release the invoice group afterwards so the service account does not leave it locked. 

Q4. How do I avoid creating duplicate AP invoices when a request times out? 

Treat a timeout as "unknown", not "failed". Before retrying, query Kinetic for an invoice with the same supplier and invoice number; update it if it is unposted and stop if it is posted. Derive any group or batch IDs from the same key so a retry lands in the same place. Add content-based duplicate checks on amount, date and lines to catch suppliers who resend the same bill under a new number. 

Q5. When should I use a BAQ instead of a business object endpoint? 

Use a BAQ when the data spans several tables, such as receipts not yet invoiced or open POs with supplier terms, and the query is something finance users already maintain. Use business object endpoints when you need a single entity with Epicor's standard fields, or when you plan to write the record back. BAQs are also easier to scope tightly, since the key can be limited to that one query. 

Q6. Will an integration built on Kinetic on-premises work after a move to Kinetic cloud? 

REST v2 integrations generally carry over with a new base URL, new API keys and possibly a new identity provider. What does not carry over is anything that bypasses REST, such as direct SQL reads or writes and Service Connect workflows running on the Epicor server. Keep the base URL, company and credentials in configuration so a cutover is a settings change rather than a code change. 

Q7. How do I find out which REST methods a Kinetic screen calls? 

Open the screen in the Kinetic browser client, open developer tools (F12), switch to the Network tab and complete the transaction by hand. Each request shows the service, method and JSON payload in order. Reproduce that sequence in a test company, carrying each returned dataset into the next call, before pointing it at production. 

Q8. Do REST API calls consume Epicor licenses? 

REST is included with Kinetic, but each call runs as an Epicor user session, and sessions are licensed. Requests sent without a reused session ID can open a new session each time, which adds load and can tie up licenses during large syncs. Confirm the license type your integration user needs with your Epicor account team, and reuse sessions in long-running jobs. 


Search

Table of Content
  1. No sections available