Entity Exploration
In this lesson you will use the cxtms gql CLI tools to discover and inspect CX entity types directly from the live GraphQL schema. This skill pays off every time you need to know an exact field name or understand what a type looks like before writing a workflow or module.
Prerequisites
You must be logged in to your CX organization:
bash1npx cxtms login
Verify the active organization before running queries:
bash1npx cxtms whoami
Step 1 — Discover the Order Type
Start by finding the GraphQL type that represents an Order in query results:
bash1npx cxtms gql types --filter order
Example output (truncated):
1OrderGqlDto2OrderCommodityGqlDto3OrderEntityGqlDto4OrderStatusGqlDto5OrderTagGqlDto6OrderAttachmentSummaryGqlDto7OrderRelatedOrdersView8...
The primary order type used in orders query results is OrderGqlDto. Inspect it:
bash1npx cxtms gql type OrderGqlDto
You will see all scalar fields, navigation properties, and computed resolvers — including customValues, orderEntities, charges, trackingEvents, and the getPort, getContact, getModeOfTransportation resolvers.
Step 2 — Inspect the Contact Type
bash1npx cxtms gql type ContactGqlDto
Key things to verify:
contactTypefield (enum: Customer, Carrier, Vendor, Driver, Employee, etc.)contactAddressescollection (each address has its owncustomValues)customValuesat the contact level
To see the ContactAddress type:
bash1npx cxtms gql type ContactAddressGqlDto
Step 3 — Find Sub-Entity Types
List order sub-entities:
bash1npx cxtms gql types --filter orderentity
Inspect the OrderEntity type:
bash1npx cxtms gql type OrderEntityGqlDto
Confirm:
entityTypefield (enum: Shipper=0, Consignee=1, Carrier=2, etc.)contactId,contactAddressIdcustomValues
Inspect TrackingEvent:
bash1npx cxtms gql type TrackingEventGqlDto
Step 4 — Audit Fields
Audit fields are inherited from AuditableEntity. Verify they exist on OrderGqlDto:
| Field | Type | Description |
|---|---|---|
created | DateTime | When the record was created |
createdBy | string | User ID who created it |
lastModified | DateTime | When it was last changed |
lastModifiedBy | string | User ID who last changed it |
createdUser | navigation | Full User object (firstName, lastName, email) |
updatedUser | navigation | Full User object |
These fields are present on all primary entities (Order, Contact, Commodity, AccountingTransaction) and most lookup entities. JobOrder is a notable exception — it uses BaseEntity and has no audit fields.
Step 5 — EntityKind Mapping Table
The entityKind identifier is used in module YAML (entityKind:) and Flow workflow triggers (entity.name:). It does not map one-to-one with entity type names:
| EntityKind | Concrete entities covered |
|---|---|
Order | All order types (Brokerage, ParcelShipment, Quote, WarehouseReceipt, AirShipmentOrder, OceanShipmentOrder, LoadOrder, DeliveryOrder, etc.) |
Contact | All contact types (Customer, Carrier, Vendor, Driver, Employee, etc.) |
OrderEntity | OrderEntity records (Shipper, Consignee, Carrier roles) |
AccountingTransaction | Invoice, Bill, CreditMemo |
Commodity | All commodities |
Calendar | CalendarEntity |
CalendarEvent | CalendarEvent |
Other | Any custom entity |
The orderType and contactType enums are filters within the EntityKind, not separate EntityKinds. A workflow triggered on EntityKind: Order fires for all order types — you then filter by entity.orderType in a condition if you need a specific type.
Step 6 — Query an Order and See customValues
Use the orders root query with a known orderId. Replace 1 with your organization ID and 123 with a real order ID:
bash1npx cxtms query '{2 orders(organizationId: 1, filter: "orderId:123", take: 1) {3 items {4 orderId5 orderNumber6 orderType7 customValues8 created9 createdBy10 orderEntities {11 entityType12 contactId13 contact { name }14 }15 trackingEvents {16 eventDefinition { eventName }17 eventDate18 location19 }20 }21 }22}'
The customValues field returns a raw JSON object. Any key-value pairs stored on the order appear here. If customValues is null or {}, the order has no custom fields set.
Step 7 — Explore the Commodity Type
bash1npx cxtms gql type CommodityGqlDto
Verify:
containerCommodityId(self-referencing parent)containerCommoditiescollection (children)weightByTotal,valueByTotalflagscustomValuesorderCommodities— each has its owncustomValues
Query a commodity with its order associations:
bash1npx cxtms query '{2 commodities(organizationId: 1, filter: "commodityId:456", take: 1) {3 items {4 commodityId5 description6 pieces7 weight8 weightUnit9 customValues10 orderCommodities {11 orderId12 customValues13 }14 }15 }16}'
Notice that Commodity.customValues and OrderCommodity.customValues are separate dictionaries. Each can hold different data.
Summary
In this lesson you:
- Used
cxtms gql types --filterto discover type names in the live schema - Used
cxtms gql typeto inspect fields onOrderGqlDto,ContactGqlDto,OrderEntityGqlDto, andCommodityGqlDto - Identified the audit fields common to all primary entities
- Learned the EntityKind mapping:
Ordercovers all order types,Contactcovers all contact types - Ran a live GraphQL query to see
customValuesdata on a real order - Confirmed that
OrderCommodity.customValuesis separate fromCommodity.customValues
Use cxtms gql type <TypeName> as your first step whenever you start building a new module or workflow — never guess field names.