Expense & Invoice API Design Best Practices

While you may view technical specifications for each Chrome River API in the Implementation Toolkit, this article covers design best practices specific to the Chrome River Expense and Invoice APIs.

See REST API Integrations Overview for complete details on Chrome River's REST API Integrations.

EntityTypes/Entity

  • Entity Type: A collection of entities.
    • For example, Companies, Cost Centers, Business Units, and Airfare Classes are all types of entities.
    • Unless your Allocation API design requires you to create new entity types, these can typically be created and maintained via the Entities Admin Screen.
  • Entities: Individual elements in an entity type.
    • For example, First Class, Business Class, and Economy Class are all entities within the Airfare Classes entity type.

Master Data entity integrations typically focus on data to support the data needed for your Allocation API design, as well as attributes that need to be related to your Person records.

  • For example, Cost Centers usually are used for both Allocation API design and Person API design, since a person can have a default cost center assigned to them.

Swagger

https://petstore.swagger.io/?url=https://service.chromeriver.com/entityapi-docs#/

Entity Resources

  • GET /v2/entities
  • POST /v1/entities

Entity Type Resources 

  • GET /v1/entity-types
  • POST /v1/entity-types
  • GET /v1/entity-types/{code}
  • PUT/v1/entity-types/{code}

Allocation

Chrome River Expense provides the ability to easily search for allocations (which your organization may refer to as matters, cost codes, or some other term) when allocating line items on an expense report. These options must be sent to Chrome River as allocation records in order for users to search for and choose where cost should be allocated. Refer to the File Integration Specification document mapped during your precon workshops with our Implementation team to understand which data the Allocation API should include.

Swagger

https://petstore.swagger.io/?url=https://service.chromeriver.com/allocationapi-docs#/

Resources

  • GET /v3/allocations
  • POST /v3/allocations
  • GET /v3/allocations/search

Closing Allocations

Be sure your Allocation API design includes a post request with the date the allocation should be closed. This will ensure that users are not using invalid allocations.

[
   {
       "allocationNumber": "0153202020",
       "allocationName": "0015",
       "clientNumber": "0015",
       "clientName": "PROD-OPS",
       "parentClientNumber": "",
       "closedDate": "2025-01-21T00:00:00Z"
   }
]

Allocation Entities

If your Allocation API design includes linking an allocation to entities to create dynamic relationships, you will need to send the name and value of each entity as follows. 

  • Name: Entity1, Entity2 or Entity3
    • This should be aligned with the allocation mapping in the Entities Admin Screen, where you specified which entity type should be mapped to each of the three entity options. 
  • Value: The entity code.
     "allocationEntities": [
           {
               "name": "Entity1",
               "value": "929400"
           }
       ],

udaPerson

If your Allocation API design includes assigning a person used in rules or reporting, you will need to send person1, person2, or person3 in the name field, along with the desired user's Unique ID. This assigns the user to one of the three person relationship attributes for the allocation. 

  • Name: person1, person2, or person3 
  • Value: The user's Unique ID.
      "udaPersons": [
           {
               "name": "person1",
               "personUniqueId": "USA00004"
           }
       ],

Person

Swagger

https://petstore.swagger.io/?url=https://service.chromeriver.com/personapi-docs#/

Primary Resources

  • GET /v4/persons
  • POST /v4/persons
  • POST /v4/persons/batch
  • GET /v4/persons/{personUniqueId}
  • PATCH /v4/persons/{personUniqueId}

Supporting Resources

The supporting resources are helpful for providing specific information for person entity attributes and person UDAs. They also allow you to make updates to those individual arrays without needing to send other person record information in the request.

  • GET /v4/persons/{personUniqueId}/person-entities
  • POST /v4/persons/{personUniqueId}/person-entities
  • GET /v4/persons/{personUniqueId}/person-entities/{person-entity-id}
  • PUT /v4/persons/{personUniqueId}/person-entities/{person-entity-id}
  • GET /v4/persons/{personUniqueId}/udas
  • POST /v4/persons/{personUniqueId}/udas

Person Entities vs. Person UDAs

Using the Person API gives your organization more flexibility in how user data is stored. In addition to the main person record fields available, you have the option to add two different types of custom fields linked to the user: Person Entities and Person UDAs. These are dynamic and do not have a limited number like other providers.

Person Entities

Person Entities are attributes of a person profile that are directly tied to an entity. Entities can be things like a Company, Cost Center, or a Department. By using an entity relationship attribute, you are ensuring that the value sent from HR is valid and is what Finance is expecting if the data needs to be sent back to the accounting system.

The user also inherits other attributes of the entity. For example, if the Department has stored Extra Data 1-5 fields, those are now tied to the user and can be part of the reporting options.

  "personEntities": [
       {
           "roleName": "Part Of",
           "entityTypeCode": "DEPT",
           "entityCode": "88003245"
       },

If these data attributes are not something that is sent to Chrome River and you do not want to manually maintain them in Chrome River, you may want to consider using Person UDAs, which are not validated against entity data.

Person UDAs

Person UDAs (User-Defined Fields) allow you to store user data that doesn’t need to be validated against entity data. These person attributes can be used for things like business rules and analytics reporting. However, if the source is a text field that can vary, you would need to account for that in the rules that are set up.

If you are interested in using Person UDAs, your Chrome River Implementation or Support contact can help you create UDAs that you can use in this integration.

UDF1, UDF2, and UDF3 are in the UDAs array block within the request, but they are stored differently in the database.
 "udas": [
       {
           "name": "UDF1",
           "value": "JOB123"
       },
       {
           "name": "Person_StartDate",
           "value": "12/15/2023"
       },
       {
           "name": "Person_DeptGroup",
           "value": "ACCOUNTING"
       }
   ]

Order, Frequency, and Timing of Requests

Resource Description Timing Recommended Frequency
Entity/EntityType EntityTypes/Entities  should be sent first because Allocation and Person APIs typically use entities in their designs. This ensures all updates are available to reduce errors in the other integrations.

Up to an array of 25 in each request

Sent Synchronous

Semi-Real-Time/Daily
Person Person updates should be sent second to ensure any new entities are available.  If person records are sent to Chrome River before entity records, data will be missing and trigger failures. If your allocation structure includes people, Person updates should be sent prior to allocation updates to prevent errors.

Up to an array of 25 in each request

Sent Synchronous using v4/persons/batch

Semi-Real-Time/Daily
Allocation If they include people in udaPerson fields, Allocations should be sent last to prevent missing data and errors. If your Allocation design doesn’t include people, you may send allocations after entities to simplify the processing on your side.  If your design includes allocationEntities, ensure that all entities are sent prior to sending Allocations so that data related to the allocation is current and available to for the necessary updates/connections within Chrome River.

Up to an array of 25 in each request

Sent Synchronous

Semi-Real-Time/Daily

 

 

 

 

 

Was this article helpful?