> ## Documentation Index
> Fetch the complete documentation index at: https://docs.coreflux.org/llms.txt
> Use this file to discover all available pages before exploring further.

# HxGN EAM (Hexagon, formerly Infor EAM)

> Client-mode REST API connector for HxGN EAM (Hexagon, formerly Infor EAM): create work orders from alarms, find released work orders through grids, add activities, comments and parts, push meter readings from MQTT counters, and update assets from machine state

Technical Preview

## Overview

HxGN EAM (Hexagon's enterprise asset management, formerly Infor EAM; newer hosts brand it Attune EAM) exposes every screen and tab as a **REST web service** under `https://<EAM host>/axis/restservices`, defined in OpenAPI 3 and browsable at `https://<EAM host>/web/swagger/index.html`. See the [HxGN EAM Rest Web Services guide](https://docs.hexagonppm.com/r/en-US/HxGN-EAM-Rest-Web-Services/12.2.1/1272545).

The **HxgnEamApi** connector maps 22 MQTT topics onto those services. Typical uses: open a work order when an alarm is raised, push runtime hours or cycle counts as asset meter readings so meter-based PM fires, set an asset out of service from the machine state, and poll released work orders back onto the broker. Each event publishes the EAM reply on `<topic>/response`.

| Event | Topic | Request (under `/axis/restservices`) | Use |
| - | - | - | - |
| `GetWorkOrderDefaults` | `cmms/hxgn-eam/work-order/defaults` | `POST /workorderdefaults` | Default values for a new work order in an organization: body \{"ORGANIZATIONID": \{"ORGANIZATIONCODE": "ORG1"}} (smoke: cheapest auth + tenant check) |
| `CreateWorkOrder` | `cmms/hxgn-eam/work-order/create` | `POST /workorders` | Add a work order from an alarm: body WORKORDERID (JOBNUM + ORGANIZATIONID, auto\_generated true), DESCRIPTION, STATUS, EQUIPMENTID, TYPE, DEPARTMENTID, ... |
| `ListWorkOrders` | `cmms/hxgn-eam/work-order/list` | `GET /workorders` | Get Collection: default Work Order Dataspy, RSCLROWS rows, no filters (use QueryGrid to filter by status) |
| `GetWorkOrder` | `cmms/hxgn-eam/work-order/get` | `GET /workorders/{id}` | One work order, id = "\<number>%23\<organization>" |
| `UpdateWorkOrder` | `cmms/hxgn-eam/work-order/update` | `PATCH /workorders/{id}` | Change only the fields sent, e.g. STATUS \{STATUSCODE: C}; recordid optional (must match if sent) |
| `DeleteWorkOrder` | `cmms/hxgn-eam/work-order/delete` | `DELETE /workorders/{id}` | Delete a work order by id |
| `AddWorkOrderActivity` | `cmms/hxgn-eam/work-order-activity/create` | `POST /workorders/activities` | Add an activity: body ACTIVITYID \{WORKORDERID, ACTIVITYCODE}, TRADEID, ESTIMATEDHOURS, PERSONS, ... |
| `ListWorkOrderActivities` | `cmms/hxgn-eam/work-order-activity/list` | `GET /workorders/{parentid}/activities` | Activities of a work order, parentid = "\<number>%23\<organization>" |
| `AddWorkOrderComment` | `cmms/hxgn-eam/work-order-comment/create` | `POST /workorders/comments` | Append machine context: body ENTITYCOMMENTID, COMMENTTEXT, PRINT (all required) |
| `ListWorkOrderComments` | `cmms/hxgn-eam/work-order-comment/list` | `GET /workorders/{parentid}/comments` | Comments of a work order (COMMENT array, RSCLROWS ignored) |
| `AddWorkOrderMeterReading` | `cmms/hxgn-eam/work-order-meter-reading/create` | `POST /workorders/meterreadings` | Meter reading on a work order: body TARGETEQUIPMENTID, USAGEUOMID, READINGDATE (required), WORKORDERID, ACTUALREADING |
| `AddWorkOrderPart` | `cmms/hxgn-eam/work-order-part/create` | `POST /workorders/parts` | Plan a part on a work order activity (Work Order Parts tab) |
| `ListWorkOrderParts` | `cmms/hxgn-eam/work-order-part/list` | `GET /workorders/{parentid}/parts` | Planned parts of a work order |
| `ListAssets` | `cmms/hxgn-eam/asset/list` | `GET /assets` | Get Collection of assets (equipment) from the default Asset Dataspy |
| `GetAsset` | `cmms/hxgn-eam/asset/get` | `GET /assets/{id}` | One asset, id = "\<equipment code>%23\<organization>" |
| `UpdateAsset` | `cmms/hxgn-eam/asset/update` | `PATCH /assets/{id}` | Change only the fields sent, e.g. OPERATIONALSTATUS, OUTOFSERVICE, INPRODUCTION from machine state |
| `AddAssetMeterReading` | `cmms/hxgn-eam/asset-meter-reading/create` | `POST /assets/meterreadings` | Runtime hours / cycles from MQTT: body EQUIPMENTID, UOMID, READINGTYPEID, READINGDATE, NEWVALUE (all required) |
| `ListAssetMeterReadings` | `cmms/hxgn-eam/asset-meter-reading/list` | `GET /assets/{parentid}/meterreadings` | Meter readings of an asset, parentid = "\<equipment code>%23\<organization>" |
| `AddAssetComment` | `cmms/hxgn-eam/asset-comment/create` | `POST /assets/comments` | Comment on an asset: body ENTITYCOMMENTID, COMMENTTEXT, PRINT |
| `ListParts` | `cmms/hxgn-eam/part/list` | `GET /parts` | Get Collection of parts from the default Part Dataspy |
| `GetPart` | `cmms/hxgn-eam/part/get` | `GET /parts/{id}` | One part, id = "\<part code>%23\<organization>" |
| `QueryGrid` | `cmms/hxgn-eam/grid/query` | `POST /grids` | Any EAM list view with filters and paging: body GRID \{GRID\_NAME e.g. WSJOBS, USER\_FUNCTION\_NAME, NUMBER\_OF\_ROWS\_FIRST\_RETURNED, CURSOR\_POSITION}, GRID\_TYPE \{TYPE: LIST}, DATASPY, ADDON\_FILTER / MULTIADDON\_FILTERS, ADDON\_SORT |

## Prerequisites

* An HxGN EAM tenant (HxGN SmartCloud, for example `eu1.eam.hxgnsmartcloud.com` or `us1.eam.hxgnsmartcloud.com`, or an on-premise server) and its **tenant id**.
* An EAM user with the **Connector** checkbox selected (HxGN EAM Products section of the user record). Install parameter `LGNCON` decides how that user signs in (`STD`, `LDAP` or `EXTERN`).
* A user group whose **Interface Permissions** grant Query, Insert, Update or Delete on each web service you call (Work Order, Work Order Activity, Comments, Meter Readings, Parts, Asset, Part, Grid).
* Default Dataspys that include the fields the services need (GET collections return the default Dataspy of the screen).
* Outbound HTTPS from the broker to the EAM host.

## Authentication

Every event sends three headers taken from the payload:

| Header | Payload field | Value |
| - | - | - |
| `Authorization` | `authorization` | `Basic <base64 user:password>`, or `Bearer <OIDC token>` (see the HxGN EAM OpenID Connect guide) |
| `tenant` | `tenant` | Your EAM tenant id |
| `organization` | `organization` | Default organization code of the user |

Store the `Authorization` value as a Hub secret, for example `HXGN_EAM_AUTHORIZATION`, and read it with `GET SECRET` in the action that publishes to the connector. The spec also accepts an API key in `X-API-Key`: fork the connector and replace the `Authorization` line with `ADD "X-API-Key" "{value.json.api_key}"`.

Optional EAM headers (`role`, `apiversion`, `keepsession` / `sessionid`, `clonedscreen`, `cursorposition`, `authenticationmode`) are not sent. Add them under `WITH HEADERS` in a fork if your tenant needs them, for example `ADD "role" "<role>"`.

A missing tenant returns `400` with `NoTenantException`; an unknown tenant returns `400` `Invalid Tenant ID: ...`.

## Configuration

| Setting | Value |
| - | - |
| `BASE_ADDRESS` | `https://eu1.eam.hxgnsmartcloud.com` (HxGN SmartCloud EU). Change it to `https://us1.eam.hxgnsmartcloud.com` or your own server; endpoints carry `/axis/restservices` |
| `USE_SSL` | `"true"` |
| `DEFAULT_CONTENT_TYPE` | `application/json` |
| Payload fields | `authorization`, `tenant`, `organization`, `id`, `parentid` (record keys), `body` (JSON request body) |

> [!WARNING]
>
> Record keys are `<code>#<organization>`, and the `#` **must be URL-encoded as `%23`** in `id` and `parentid`, for example `"10000%23ORG1"` for work order 10000 in ORG1 or `"PUMP-101%23ORG1"` for an asset. A raw `#` starts a URL fragment, so the organization never reaches EAM and the call fails with `404`.

* **Lists.** `ListWorkOrders`, `ListAssets` and `ListParts` take no filters: they return the screen's default Dataspy, `RSCLROWS` rows at a time. To filter (for example work orders in status `R`), use `QueryGrid` (`POST /grids`) with `GRID_NAME` `WSJOBS` and an `ADDON_FILTER`, or a Dataspy id. Grid alias names and Dataspy ids depend on your tenant; check them in the grid response.
* **Writes.** `POST` adds a record. `PATCH` changes only the fields you send; include the key block (`WORKORDERID` or `ASSETID`) as in the Swagger patch example. If you send `recordid`, it must match the stored value, or EAM answers "This record has been modified by another user". `PUT` (Sync, full replace that blanks missing fields) is not packaged.
* **Required fields.** Work orders: `WORKORDERID`, `STATUS`, `DEPARTMENTID`, `FIXED`. Asset meter readings: `EQUIPMENTID`, `UOMID`, `READINGTYPEID`, `READINGDATE`, `NEWVALUE`. Comments: `ENTITYCOMMENTID`, `COMMENTTEXT`, `PRINT`. `GetWorkOrderDefaults` returns the defaults for an organization.
* **Numbers and dates.** Quantities are `{"VALUE", "NUMOFDEC", "SIGN", "UOM"}` objects (`VALUE` 128750 with `NUMOFDEC` 2 is 1287.50). Date objects carry `YEAR` as epoch milliseconds unless install parameter `RSYRYYYY` is `YES` (EAM 12.3+).

## Basic Syntax

```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
# Coreflux REST_API template — HxGN EAM REST Web Services (Hexagon, formerly Infor EAM; recent hosts brand it Attune EAM):
#   create work orders from alarms, read / list / patch / delete work orders, add activities, comments and planned parts,
#   push meter readings from MQTT counters (asset or work-order meter readings), read and patch assets (equipment),
#   read parts, and query any EAM grid (list view with filters, e.g. work orders in status R).
# Hugo catalog #169, Tier 2 (cmms). Spec: official HxGN EAM OpenAPI 3.0.1 files served by every EAM host at
#   /web/swagger/api/<Service>.json (fetched from eu1.eam.hxgnsmartcloud.com, curated slim in openapi-cache/hxgn-eam.json).
#   Credentials are placeholders only.
# Docs: https://docs.coreflux.org/latest/lot-language/routes/rest-api-apps/hxgn-eam
#
# Host: BASE_ADDRESS is the EAM application server. HxGN SmartCloud EU is https://eu1.eam.hxgnsmartcloud.com (US: us1...);
#   on-premise or older Infor-hosted tenants use their own host. Every endpoint carries /axis/restservices.
# Headers: tenant and organization are required on every call (spec), taken from {value.json.tenant} and
#   {value.json.organization}. Optional headers (role, apiversion, keepsession, sessionid, clonedscreen,
#   cursorposition, authenticationmode) are not sent; fork the route to add them (e.g. ADD "role" "<role>").
# Auth: Authorization: {value.json.authorization} carries the full header value, "Basic <base64 user:password>" for an
#   EAM user with the Connector checkbox, or "Bearer <OIDC token>" (HxGN EAM OpenID Connect guide). The spec also allows
#   an X-API-Key header: fork and replace the Authorization line with ADD "X-API-Key" "{value.json.api_key}".
#   Keep the value in Hub secrets (suggested HXGN_EAM_AUTHORIZATION) and map it into the payload with GET SECRET.
#   The user group needs Interface Permissions (Query / Insert / Update / Delete) on each web service you call.
# Ids: id / parentid are "<code>#<organization>" and the # MUST be sent URL-encoded as %23, e.g. "10000%23ORG1"
#   (work order 10000 in organization ORG1) or "PUMP-101%23ORG1" (asset). The broker does not encode path values.
# Lists: GET collections take no filters; they return the default Dataspy of the screen, RSCLROWS rows. For a filtered
#   list (for example work orders in status R) use QueryGrid (POST /grids) with GRID_NAME WSJOBS + ADDON_FILTER.
# Writes: POST adds, PATCH changes only the fields sent (recordid, if sent, must match). PUT (Sync, full replace that
#   blanks missing fields) is deliberately not packaged. Dates are {"YEAR": <epoch ms>, "MONTH", "DAY", ...} objects
#   unless install parameter RSYRYYYY = YES (EAM 12.3+).
# Responses: 200 {"Result": {"ResultData": ..., "InfoAlert", "WarningAlert"}, "ErrorAlert": null, ...};
#   400 ErrorAlert or ConfirmationAlert (e.g. "Invalid Tenant ID", validation, "record modified by another user");
#   404 unknown service / record; 500 internal error.
#
# Payload fields (control fields stay out of bodies; request bodies come from {value.json.body}):
#   authorization, tenant, organization, id, parentid, body
#     CreateWorkOrder        body = {"WORKORDERID": {"JOBNUM": "", "ORGANIZATIONID": {"ORGANIZATIONCODE": "ORG1"}, "auto_generated": true},
#                                    "DESCRIPTION": "Compressor over-temperature", "STATUS": {"STATUSCODE": "R"},
#                                    "EQUIPMENTID": {"EQUIPMENTCODE": "PUMP-101", "ORGANIZATIONID": {"ORGANIZATIONCODE": "ORG1"}},
#                                    "TYPE": {"TYPECODE": "BRKD"}, "DEPARTMENTID": {"DEPARTMENTCODE": "*"}, "FIXED": "V"}
#                            (schema-required: WORKORDERID, STATUS, DEPARTMENTID, FIXED; call GetWorkOrderDefaults for your defaults)
#     UpdateWorkOrder        id = "10000%23ORG1", body = {"WORKORDERID": {"JOBNUM": "10000", "ORGANIZATIONID": {"ORGANIZATIONCODE": "ORG1"}},
#                                                       "STATUS": {"STATUSCODE": "C"}}   (PATCH carries the key block + changed fields)
#     AddAssetMeterReading   body = {"EQUIPMENTID": {"EQUIPMENTCODE": "PUMP-101", "ORGANIZATIONID": {"ORGANIZATIONCODE": "ORG1"}},
#                                    "UOMID": {"UOMCODE": "HR"}, "READINGTYPEID": {"READINGTYPECODE": "..."},
#                                    "READINGDATE": {"YEAR": 1759658100000, "MONTH": 10, "DAY": 5, "HOUR": 10, "MINUTE": 15, "SECOND": 0,
#                                                    "SUBSECOND": 0, "TIMEZONE": "+0100", "qualifier": "OTHER"},
#                                    "NEWVALUE": {"VALUE": 128750, "NUMOFDEC": 2, "SIGN": "+", "UOM": "HR", "qualifier": "OTHER"}}
#     QueryGrid              body = {"GRID": {"GRID_NAME": "WSJOBS", "USER_FUNCTION_NAME": "WSJOBS", "NUMBER_OF_ROWS_FIRST_RETURNED": 50},
#                                    "GRID_TYPE": {"TYPE": "LIST"}, "ADDON_FILTER": {"ALIAS_NAME": "workorderstatus", "OPERATOR": "=", "VALUE": "R"},
#                                    "REQUEST_TYPE": "LIST.HEAD_DATA.STORED"}
#

DEFINE ROUTE HxgnEamApi WITH TYPE REST_API
    ADD REST_API_CONFIG
        WITH BASE_ADDRESS "https://eu1.eam.hxgnsmartcloud.com"
        WITH ENABLE_CLIENT "true"
        WITH USE_SSL "true"
        WITH REQUEST_TIMEOUT '30'
        WITH DEFAULT_CONTENT_TYPE "application/json"
        # Smoke: GetWorkOrderDefaults -> CreateWorkOrder -> QueryGrid (WSJOBS status R) -> GetWorkOrder -> UpdateWorkOrder -> AddWorkOrderComment -> AddAssetMeterReading -> DeleteWorkOrder.
    ADD EVENT GetWorkOrderDefaults
        WITH SOURCE_TOPIC "cmms/hxgn-eam/work-order/defaults"
        WITH DESTINATION_TOPIC "cmms/hxgn-eam/work-order/defaults/response"
        WITH METHOD "POST"
        WITH ENDPOINT "/axis/restservices/workorderdefaults"
        WITH HEADERS
            ADD "Accept" "application/json"
            ADD "Authorization" "{value.json.authorization}"
            ADD "tenant" "{value.json.tenant}"
            ADD "organization" "{value.json.organization}"
            ADD "Content-Type" "application/json"
        WITH BODY "{value.json.body}"
    ADD EVENT CreateWorkOrder
        WITH SOURCE_TOPIC "cmms/hxgn-eam/work-order/create"
        WITH DESTINATION_TOPIC "cmms/hxgn-eam/work-order/create/response"
        WITH METHOD "POST"
        WITH ENDPOINT "/axis/restservices/workorders"
        WITH HEADERS
            ADD "Accept" "application/json"
            ADD "Authorization" "{value.json.authorization}"
            ADD "tenant" "{value.json.tenant}"
            ADD "organization" "{value.json.organization}"
            ADD "Content-Type" "application/json"
        WITH BODY "{value.json.body}"
    ADD EVENT ListWorkOrders
        WITH SOURCE_TOPIC "cmms/hxgn-eam/work-order/list"
        WITH DESTINATION_TOPIC "cmms/hxgn-eam/work-order/list/response"
        WITH METHOD "GET"
        WITH ENDPOINT "/axis/restservices/workorders"
        WITH HEADERS
            ADD "Accept" "application/json"
            ADD "Authorization" "{value.json.authorization}"
            ADD "tenant" "{value.json.tenant}"
            ADD "organization" "{value.json.organization}"
    ADD EVENT GetWorkOrder
        WITH SOURCE_TOPIC "cmms/hxgn-eam/work-order/get"
        WITH DESTINATION_TOPIC "cmms/hxgn-eam/work-order/get/response"
        WITH METHOD "GET"
        WITH ENDPOINT "/axis/restservices/workorders/{value.json.id}"
        WITH HEADERS
            ADD "Accept" "application/json"
            ADD "Authorization" "{value.json.authorization}"
            ADD "tenant" "{value.json.tenant}"
            ADD "organization" "{value.json.organization}"
    ADD EVENT UpdateWorkOrder
        WITH SOURCE_TOPIC "cmms/hxgn-eam/work-order/update"
        WITH DESTINATION_TOPIC "cmms/hxgn-eam/work-order/update/response"
        WITH METHOD "PATCH"
        WITH ENDPOINT "/axis/restservices/workorders/{value.json.id}"
        WITH HEADERS
            ADD "Accept" "application/json"
            ADD "Authorization" "{value.json.authorization}"
            ADD "tenant" "{value.json.tenant}"
            ADD "organization" "{value.json.organization}"
            ADD "Content-Type" "application/json"
        WITH BODY "{value.json.body}"
    ADD EVENT DeleteWorkOrder
        WITH SOURCE_TOPIC "cmms/hxgn-eam/work-order/delete"
        WITH DESTINATION_TOPIC "cmms/hxgn-eam/work-order/delete/response"
        WITH METHOD "DELETE"
        WITH ENDPOINT "/axis/restservices/workorders/{value.json.id}"
        WITH HEADERS
            ADD "Accept" "application/json"
            ADD "Authorization" "{value.json.authorization}"
            ADD "tenant" "{value.json.tenant}"
            ADD "organization" "{value.json.organization}"
    ADD EVENT AddWorkOrderActivity
        WITH SOURCE_TOPIC "cmms/hxgn-eam/work-order-activity/create"
        WITH DESTINATION_TOPIC "cmms/hxgn-eam/work-order-activity/create/response"
        WITH METHOD "POST"
        WITH ENDPOINT "/axis/restservices/workorders/activities"
        WITH HEADERS
            ADD "Accept" "application/json"
            ADD "Authorization" "{value.json.authorization}"
            ADD "tenant" "{value.json.tenant}"
            ADD "organization" "{value.json.organization}"
            ADD "Content-Type" "application/json"
        WITH BODY "{value.json.body}"
    ADD EVENT ListWorkOrderActivities
        WITH SOURCE_TOPIC "cmms/hxgn-eam/work-order-activity/list"
        WITH DESTINATION_TOPIC "cmms/hxgn-eam/work-order-activity/list/response"
        WITH METHOD "GET"
        WITH ENDPOINT "/axis/restservices/workorders/{value.json.parentid}/activities"
        WITH HEADERS
            ADD "Accept" "application/json"
            ADD "Authorization" "{value.json.authorization}"
            ADD "tenant" "{value.json.tenant}"
            ADD "organization" "{value.json.organization}"
    ADD EVENT AddWorkOrderComment
        WITH SOURCE_TOPIC "cmms/hxgn-eam/work-order-comment/create"
        WITH DESTINATION_TOPIC "cmms/hxgn-eam/work-order-comment/create/response"
        WITH METHOD "POST"
        WITH ENDPOINT "/axis/restservices/workorders/comments"
        WITH HEADERS
            ADD "Accept" "application/json"
            ADD "Authorization" "{value.json.authorization}"
            ADD "tenant" "{value.json.tenant}"
            ADD "organization" "{value.json.organization}"
            ADD "Content-Type" "application/json"
        WITH BODY "{value.json.body}"
    ADD EVENT ListWorkOrderComments
        WITH SOURCE_TOPIC "cmms/hxgn-eam/work-order-comment/list"
        WITH DESTINATION_TOPIC "cmms/hxgn-eam/work-order-comment/list/response"
        WITH METHOD "GET"
        WITH ENDPOINT "/axis/restservices/workorders/{value.json.parentid}/comments"
        WITH HEADERS
            ADD "Accept" "application/json"
            ADD "Authorization" "{value.json.authorization}"
            ADD "tenant" "{value.json.tenant}"
            ADD "organization" "{value.json.organization}"
    ADD EVENT AddWorkOrderMeterReading
        WITH SOURCE_TOPIC "cmms/hxgn-eam/work-order-meter-reading/create"
        WITH DESTINATION_TOPIC "cmms/hxgn-eam/work-order-meter-reading/create/response"
        WITH METHOD "POST"
        WITH ENDPOINT "/axis/restservices/workorders/meterreadings"
        WITH HEADERS
            ADD "Accept" "application/json"
            ADD "Authorization" "{value.json.authorization}"
            ADD "tenant" "{value.json.tenant}"
            ADD "organization" "{value.json.organization}"
            ADD "Content-Type" "application/json"
        WITH BODY "{value.json.body}"
    ADD EVENT AddWorkOrderPart
        WITH SOURCE_TOPIC "cmms/hxgn-eam/work-order-part/create"
        WITH DESTINATION_TOPIC "cmms/hxgn-eam/work-order-part/create/response"
        WITH METHOD "POST"
        WITH ENDPOINT "/axis/restservices/workorders/parts"
        WITH HEADERS
            ADD "Accept" "application/json"
            ADD "Authorization" "{value.json.authorization}"
            ADD "tenant" "{value.json.tenant}"
            ADD "organization" "{value.json.organization}"
            ADD "Content-Type" "application/json"
        WITH BODY "{value.json.body}"
    ADD EVENT ListWorkOrderParts
        WITH SOURCE_TOPIC "cmms/hxgn-eam/work-order-part/list"
        WITH DESTINATION_TOPIC "cmms/hxgn-eam/work-order-part/list/response"
        WITH METHOD "GET"
        WITH ENDPOINT "/axis/restservices/workorders/{value.json.parentid}/parts"
        WITH HEADERS
            ADD "Accept" "application/json"
            ADD "Authorization" "{value.json.authorization}"
            ADD "tenant" "{value.json.tenant}"
            ADD "organization" "{value.json.organization}"
    ADD EVENT ListAssets
        WITH SOURCE_TOPIC "cmms/hxgn-eam/asset/list"
        WITH DESTINATION_TOPIC "cmms/hxgn-eam/asset/list/response"
        WITH METHOD "GET"
        WITH ENDPOINT "/axis/restservices/assets"
        WITH HEADERS
            ADD "Accept" "application/json"
            ADD "Authorization" "{value.json.authorization}"
            ADD "tenant" "{value.json.tenant}"
            ADD "organization" "{value.json.organization}"
    ADD EVENT GetAsset
        WITH SOURCE_TOPIC "cmms/hxgn-eam/asset/get"
        WITH DESTINATION_TOPIC "cmms/hxgn-eam/asset/get/response"
        WITH METHOD "GET"
        WITH ENDPOINT "/axis/restservices/assets/{value.json.id}"
        WITH HEADERS
            ADD "Accept" "application/json"
            ADD "Authorization" "{value.json.authorization}"
            ADD "tenant" "{value.json.tenant}"
            ADD "organization" "{value.json.organization}"
    ADD EVENT UpdateAsset
        WITH SOURCE_TOPIC "cmms/hxgn-eam/asset/update"
        WITH DESTINATION_TOPIC "cmms/hxgn-eam/asset/update/response"
        WITH METHOD "PATCH"
        WITH ENDPOINT "/axis/restservices/assets/{value.json.id}"
        WITH HEADERS
            ADD "Accept" "application/json"
            ADD "Authorization" "{value.json.authorization}"
            ADD "tenant" "{value.json.tenant}"
            ADD "organization" "{value.json.organization}"
            ADD "Content-Type" "application/json"
        WITH BODY "{value.json.body}"
    ADD EVENT AddAssetMeterReading
        WITH SOURCE_TOPIC "cmms/hxgn-eam/asset-meter-reading/create"
        WITH DESTINATION_TOPIC "cmms/hxgn-eam/asset-meter-reading/create/response"
        WITH METHOD "POST"
        WITH ENDPOINT "/axis/restservices/assets/meterreadings"
        WITH HEADERS
            ADD "Accept" "application/json"
            ADD "Authorization" "{value.json.authorization}"
            ADD "tenant" "{value.json.tenant}"
            ADD "organization" "{value.json.organization}"
            ADD "Content-Type" "application/json"
        WITH BODY "{value.json.body}"
    ADD EVENT ListAssetMeterReadings
        WITH SOURCE_TOPIC "cmms/hxgn-eam/asset-meter-reading/list"
        WITH DESTINATION_TOPIC "cmms/hxgn-eam/asset-meter-reading/list/response"
        WITH METHOD "GET"
        WITH ENDPOINT "/axis/restservices/assets/{value.json.parentid}/meterreadings"
        WITH HEADERS
            ADD "Accept" "application/json"
            ADD "Authorization" "{value.json.authorization}"
            ADD "tenant" "{value.json.tenant}"
            ADD "organization" "{value.json.organization}"
    ADD EVENT AddAssetComment
        WITH SOURCE_TOPIC "cmms/hxgn-eam/asset-comment/create"
        WITH DESTINATION_TOPIC "cmms/hxgn-eam/asset-comment/create/response"
        WITH METHOD "POST"
        WITH ENDPOINT "/axis/restservices/assets/comments"
        WITH HEADERS
            ADD "Accept" "application/json"
            ADD "Authorization" "{value.json.authorization}"
            ADD "tenant" "{value.json.tenant}"
            ADD "organization" "{value.json.organization}"
            ADD "Content-Type" "application/json"
        WITH BODY "{value.json.body}"
    ADD EVENT ListParts
        WITH SOURCE_TOPIC "cmms/hxgn-eam/part/list"
        WITH DESTINATION_TOPIC "cmms/hxgn-eam/part/list/response"
        WITH METHOD "GET"
        WITH ENDPOINT "/axis/restservices/parts"
        WITH HEADERS
            ADD "Accept" "application/json"
            ADD "Authorization" "{value.json.authorization}"
            ADD "tenant" "{value.json.tenant}"
            ADD "organization" "{value.json.organization}"
    ADD EVENT GetPart
        WITH SOURCE_TOPIC "cmms/hxgn-eam/part/get"
        WITH DESTINATION_TOPIC "cmms/hxgn-eam/part/get/response"
        WITH METHOD "GET"
        WITH ENDPOINT "/axis/restservices/parts/{value.json.id}"
        WITH HEADERS
            ADD "Accept" "application/json"
            ADD "Authorization" "{value.json.authorization}"
            ADD "tenant" "{value.json.tenant}"
            ADD "organization" "{value.json.organization}"
    ADD EVENT QueryGrid
        WITH SOURCE_TOPIC "cmms/hxgn-eam/grid/query"
        WITH DESTINATION_TOPIC "cmms/hxgn-eam/grid/query/response"
        WITH METHOD "POST"
        WITH ENDPOINT "/axis/restservices/grids"
        WITH HEADERS
            ADD "Accept" "application/json"
            ADD "Authorization" "{value.json.authorization}"
            ADD "tenant" "{value.json.tenant}"
            ADD "organization" "{value.json.organization}"
            ADD "Content-Type" "application/json"
        WITH BODY "{value.json.body}"
```

## Examples

Publish directly to a connector topic:

```json theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
{"authorization": "Basic <base64 user:password>", "tenant": "YOUR_TENANT", "organization": "ORG1", "id": "10000%23ORG1"}
```

to `cmms/hxgn-eam/work-order/get`, then read `cmms/hxgn-eam/work-order/get/response`.

Actions that feed the connector from plant data:

```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
# Example actions for the HxgnEamApi route (docs page). Not part of the route template.
# Secret: HXGN_EAM_AUTHORIZATION = "Basic <base64 user:password>" for an EAM user with the Connector checkbox
#   (or "Bearer <OIDC token>"). Tenant and organization are not secret; replace YOUR_TENANT and ORG1.
# Ids in paths are "<code>%23<organization>" (the # URL-encoded). Codes below (PUMP-101, BRKD, HR, TOTAL) are examples;
#   use the values configured in your EAM tenant (GetWorkOrderDefaults returns the defaults for an organization).
# Dates: EAM date objects carry YEAR as epoch milliseconds unless install parameter RSYRYYYY = YES (EAM 12.3+), so the
#   edge payload below already carries the epoch ms and the date parts.

DEFINE ACTION HxgnEamWorkOrderFromAlarm
ON TOPIC "plant/line1/alarm/raised" DO
    SET "auth" WITH GET SECRET "HXGN_EAM_AUTHORIZATION"
    SET "alarm" WITH (GET JSON "alarm" IN PAYLOAD AS STRING)
    SET "value" WITH (GET JSON "value" IN PAYLOAD AS STRING)
    SET "desc" WITH "Coreflux alarm " + {alarm} + " (value " + {value} + ")"
    PUBLISH TOPIC "cmms/hxgn-eam/work-order/create" WITH { "authorization": {auth}, "tenant": "YOUR_TENANT", "organization": "ORG1", "body": { "WORKORDERID": { "JOBNUM": "", "ORGANIZATIONID": { "ORGANIZATIONCODE": "ORG1" }, "auto_generated": true }, "DESCRIPTION": {desc}, "STATUS": { "STATUSCODE": "R" }, "EQUIPMENTID": { "EQUIPMENTCODE": "PUMP-101", "ORGANIZATIONID": { "ORGANIZATIONCODE": "ORG1" } }, "TYPE": { "TYPECODE": "BRKD" }, "DEPARTMENTID": { "DEPARTMENTCODE": "*" }, "FIXED": "V" } }

DEFINE ACTION HxgnEamRuntimeHoursReading
ON TOPIC "plant/line1/pump101/runtime" DO
    SET "auth" WITH GET SECRET "HXGN_EAM_AUTHORIZATION"
    SET "hours" WITH (GET JSON "hours" IN PAYLOAD AS INT)
    SET "ms" WITH (GET JSON "epoch_ms" IN PAYLOAD AS INT)
    SET "mo" WITH (GET JSON "month" IN PAYLOAD AS INT)
    SET "dd" WITH (GET JSON "day" IN PAYLOAD AS INT)
    SET "hh" WITH (GET JSON "hour" IN PAYLOAD AS INT)
    SET "mi" WITH (GET JSON "minute" IN PAYLOAD AS INT)
    PUBLISH TOPIC "cmms/hxgn-eam/asset-meter-reading/create" WITH { "authorization": {auth}, "tenant": "YOUR_TENANT", "organization": "ORG1", "body": { "EQUIPMENTID": { "EQUIPMENTCODE": "PUMP-101", "ORGANIZATIONID": { "ORGANIZATIONCODE": "ORG1" } }, "UOMID": { "UOMCODE": "HR" }, "READINGTYPEID": { "READINGTYPECODE": "TOTAL" }, "READINGDATE": { "YEAR": {ms}, "MONTH": {mo}, "DAY": {dd}, "HOUR": {hh}, "MINUTE": {mi}, "SECOND": 0, "SUBSECOND": 0, "TIMEZONE": "+0000", "qualifier": "OTHER" }, "NEWVALUE": { "VALUE": {hours}, "NUMOFDEC": 0, "SIGN": "+", "UOM": "HR", "qualifier": "OTHER" } } }

DEFINE ACTION HxgnEamAssetOutOfServiceFromMachineState
ON TOPIC "plant/line1/pump101/state" DO
    SET "auth" WITH GET SECRET "HXGN_EAM_AUTHORIZATION"
    SET "state" WITH PAYLOAD AS STRING
    IF {state} EQUALS "running" THEN
        PUBLISH TOPIC "cmms/hxgn-eam/asset/update" WITH { "authorization": {auth}, "tenant": "YOUR_TENANT", "organization": "ORG1", "id": "PUMP-101%23ORG1", "body": { "ASSETID": { "EQUIPMENTCODE": "PUMP-101", "ORGANIZATIONID": { "ORGANIZATIONCODE": "ORG1" } }, "OUTOFSERVICE": "false" } }
    ELSE
        PUBLISH TOPIC "cmms/hxgn-eam/asset/update" WITH { "authorization": {auth}, "tenant": "YOUR_TENANT", "organization": "ORG1", "id": "PUMP-101%23ORG1", "body": { "ASSETID": { "EQUIPMENTCODE": "PUMP-101", "ORGANIZATIONID": { "ORGANIZATIONCODE": "ORG1" } }, "OUTOFSERVICE": "true" } }

DEFINE ACTION HxgnEamPollReleasedWorkOrders
ON EVERY 15 MINUTES DO
    SET "auth" WITH GET SECRET "HXGN_EAM_AUTHORIZATION"
    PUBLISH TOPIC "cmms/hxgn-eam/grid/query" WITH { "authorization": {auth}, "tenant": "YOUR_TENANT", "organization": "ORG1", "body": { "GRID": { "GRID_NAME": "WSJOBS", "USER_FUNCTION_NAME": "WSJOBS", "NUMBER_OF_ROWS_FIRST_RETURNED": 50 }, "GRID_TYPE": { "TYPE": "LIST" }, "ADDON_FILTER": { "ALIAS_NAME": "workorderstatus", "OPERATOR": "=", "VALUE": "R" }, "REQUEST_TYPE": "LIST.HEAD_DATA.STORED" } }
```

Restrict who can publish to `cmms/hxgn-eam/#` with a rule: its payloads carry EAM credentials and can create and delete work orders.

## Responses

Every reply uses the EAM envelope: `Result.ResultData` holds the data on `200`, `Result.InfoAlert` / `WarningAlert` carry messages, and `ErrorAlert` or `ConfirmationAlert` is set on `400`. `404` means an unknown service or record, `500` an internal error. With `keepsession: true` (fork), `Result.SessionID` can be reused in a `sessionid` header.

## Notes

* The catalog listed OAuth 2.0 through the Infor ION API gateway. Current HxGN EAM tenants publish `basicAuth`, `apiKey` (`X-API-Key`) and `bearerAuth` (OIDC) in their OpenAPI files; the ION gateway only applies to legacy Infor-hosted tenants and is not packaged.
* Work order statuses, types (`BRKD`, ...), departments, UOMs and reading types are tenant codes. The values in the examples are placeholders.
* HxGN EAM has no webhook API in the REST guide. Poll with `QueryGrid` or the list events.
* SOAP web services (`/axis/services/EWSConnector`) also exist; this connector uses REST only.

## Testing

Static checks against the official OpenAPI files, a local contract mock covering all 22 events with negative controls, and real unauthenticated probes against HxGN SmartCloud (fake tenant, `400 Invalid Tenant ID` on every event before any login) pass. A run against a real tenant and a broker MQTT round-trip are still open.

## Not covered

PUT (Sync) and DELETE on child records, work order book labor, checklists, schedules, purchasing, stores, PM schedules, cases, documents and the CSV grid service. All are in the EAM Swagger and can be added to a fork.

## Related

* [REST API Connectors](/latest/lot-language/routes/rest-api-routes)
* [REST API app templates](/latest/lot-language/routes/rest-api-apps/index)
* [MaintainX](/latest/lot-language/routes/rest-api-apps/maintainx)
* [IBM Maximo Manage](/latest/lot-language/routes/rest-api-apps/ibm-maximo-manage)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.