# Epicor REST API v2: OData Filter, Select and Expand Examples

> Source: https://netray.co/erp-help/epicor-rest-v2-odata-filter-query-examples
> Publisher: Netray (netray.co), AI and integration engineering for ERP and manufacturing systems.
> Section: ERP Help

## Short answer

Epicor Kinetic REST v2 exposes business objects at /api/v2/odata/{Company}/{Service}/{Entity} and BAQs at /api/v2/odata/{Company}/BaqSvc/{BAQId}/Data. Send an API key in the x-api-key header plus credentials, and use standard OData options: $filter, $select, $top, $skip, $orderby and $expand.

## Kind

how-to

## System

epicor

## Erp

Epicor Kinetic

## Module

REST API v2 / OData

## Query

Epicor REST API v2 OData filter example

## Alternate Queries

- Epicor REST v2 $filter $select $top
- Epicor API call to get jobs odata
- Epicor REST API x-api-key header example
- Epicor BAQ via REST v2 odata

## Applies To

Epicor Kinetic 2021.x to current with REST v2 enabled; v1 uses a different URL pattern and is not covered here

## Steps

### Make your first useful call

**Items:**

- Generate an API key in Epicor: API Key Maintenance, for the user or integration account, and note the key value.
- Build the base URL: https://yourserver/yourinstance/api/v2/odata/{Company}/ followed by the service and entity.
- Send two headers: x-api-key with the key, and Authorization with Basic credentials or a bearer token, depending on your authentication setup.
- Request a small result first: add $top=5 to confirm connectivity and see the property names exactly as spelled.
- Add $select to return only the columns you need; it reduces payload and avoids exposing unneeded data.
- Add $filter to narrow rows. Use eq, ne, gt, lt, and, or, and string functions such as startswith and contains.
- Page with $top and $skip, or follow the @odata.nextLink value in the response, until no more rows return.
- Call a BAQ by name from BaqSvc, and pass filter values as OData options on the BAQ result fields.

## Sections

### URL patterns and examples

**Body:**

The service name matches the business object service, such as Erp.BO.JobEntrySvc, Erp.BO.PartSvc or Erp.BO.SalesOrderSvc, and the entity is the table-like collection exposed by it, such as Jobs, Parts or OrderHeds. The easiest way to learn the exact names is the REST help page on your own server, which lists services and fields for your version.

String values in a filter need single quotes. Dates use the OData format, either with a datetime literal or a date function. Spaces in the URL must be encoded as %20 in a raw HTTP client, though most libraries do this for you.

**Code:**

- GET /api/v2/odata/EPIC06/Erp.BO.JobEntrySvc/JobHeads?$select=JobNum,PartNum,JobReleased&$filter=JobReleased eq true and JobClosed eq false&$top=50&$orderby=JobNum desc
- GET /api/v2/odata/EPIC06/Erp.BO.PartSvc/Parts?$filter=startswith(PartNum,'AX-') and InActive eq false&$select=PartNum,PartDescription,TypeCode
- GET /api/v2/odata/EPIC06/BaqSvc/MyOpenJobs/Data?$filter=JobHead_JobNum eq 'J-100234'

### Headers, authentication and what 401 and 403 mean

**Body:**

REST v2 normally needs the API key and a valid user. A missing key returns an error that names the key, while bad credentials give a 401. A 403 usually means the user authenticated but has no security for that service or company, so check the user's security group and the company in the URL.

Do not put credentials in URLs and do not log request headers. Keep keys in a secrets store and give the integration its own Epicor user with the minimum rights, so a leaked key has limited reach. For the 401 case in detail, see the dedicated page on that error.

**Code:**

curl -s "https://erp.example.com/prod/api/v2/odata/EPIC06/Erp.BO.PartSvc/Parts?$top=5&$select=PartNum" -H "x-api-key: YOUR_KEY" -H "Authorization: Basic BASE64_USER_PASS" -H "Accept: application/json"

### Expand, paging and write calls

**Body:**

$expand pulls child collections in one call, for example a job's assemblies and materials, but each expansion multiplies payload size. Use it for a single record or a small page; for bulk, make separate calls per entity and join in your own code.

Results are capped by server settings. If you ask for more than the page size, you get a nextLink to follow. Always loop until it is absent rather than assuming one response is complete. For writes, use the business object's methods, such as the GetNew and Update methods, so BPM and validation run. Posting straight to a table entity is rarely what you want.

### BAQ endpoints and performance

**Body:**

A BAQ exposed through BaqSvc is often the best integration source. It lets an Epicor developer write the joins and filters once, tested and secured, and the integration reads a stable, flat result. Column names come back in the form Table_Column.

Keep $filter on indexed or key fields where possible. A filter on a computed BAQ field cannot use an index and may scan. For large extracts, schedule them off-hours and page them.

## Pitfalls

- Forgetting the x-api-key header and treating the resulting error as a bad password.
- Writing field names from memory; property names are case sensitive and version specific.
- Requesting a huge $expand tree and timing out the server or the client.
- Ignoring the nextLink and quietly truncating a data extract at the page size.
- Using a high-privilege user for the integration instead of a least-privilege service account.

## Ai Angle

A grounded assistant such as ERPray reads the metadata of your Epicor instance to build correct OData URLs with real entity and field names, then runs read-only queries under the caller's own Epicor role and shows the exact request it made. That removes most guesswork about names and filters, and keeps data access inside the same security as a normal user.

## Faq

### What is the difference between Epicor REST v1 and v2?

**Answer:** REST v2 is the newer OData based interface with a consistent URL pattern, API key support and better metadata. Version 1 uses an older URL layout and is being phased out in favour of v2 in Kinetic. New integrations should use v2 and plan to move existing v1 calls.

### How do I filter by date in Epicor OData?

**Answer:** Use an ISO style datetime comparison such as ChangeDate gt 2026-01-01T00:00:00Z, or the OData date functions where supported. The exact accepted format depends on the field type and version, so test with $top first. Timezone handling is a common source of off-by-one-day results.

### Can I call a BAQ with parameters through REST?

**Answer:** Yes. Call the BAQ through BaqSvc and filter on its output fields with $filter, or use the BAQ's own parameters via the query options your version supports. Filtering on output columns is the most portable approach across Kinetic releases.

### Why does my Epicor REST call return an empty list?

**Answer:** Check the company in the URL, the filter value spelling and case, and whether the user's security hides the data. Remove the filter and use $top=5 to confirm any rows return. An empty result with a 200 status is often a filter on the wrong field name or the wrong company.

## Search terms

epicor rest api v2, epicor odata filter, epicor api key x-api-key, epicor rest api example, epicor baqsvc odata, epicor odata expand, epicor kinetic api, epicor rest paging nextlink, epicor jobentrysvc rest

---
Talk to an engineer: https://netray.co/contact?intent=erp_ai | Machine catalog: https://netray.co/agent/catalog.json
