Dealer ECM Reports API
CAT© Rental Store - Dealer Data Pull Interface Version 2.0
Modification History
Date | Author | Description of Change |
---|---|---|
07/25/19 | Sam Bridger | New Document |
08/06/19 | Sam Bridger | Revisions after testing, clarification. |
08/20/19 | Sam Bridger | Finalizing for review |
08/27/19 | Sam Bridger | Final version sent for review by DICE team |
09/30/19 | Sam Bridger | Revisions from DICE team review, uprev to 1.1 |
01/08/20 | Sam Bridger | Revisions to customer endpoint |
01/30/20 | Sam Bridger | Added clarification to invoice endpoint specifying order |
02/20/20 | Sam Bridger | Fixing case on some variable names. Uprev to 1.2 |
03/04/20 | Sam Bridger | Added Array Sizes |
02/11/21 | Sam Bridger | Added clarification to Security/Authentication Considerations and overview Added fields for additional information around cycle bill dates in contracts Added field to contract to allow URL for contract PDF Added field to invoice to allow for URL for invoice PDF Added date fields and calloff confirmation to individual assets on contracts Fixed equipmentAssetId to be required on assets in contracts Added clarification to catalog description Added country to jobsite and dealer location Removed paging from catalog endpoint response Fixed typos / swapped fields Added to and clarified Process Description Uprev to 1.3 |
04/08/21 | David Winkel | Integrated Array Sizes with data layouts Added release notes to clarify upgrade path for dealers who have already implemented an earlier version of this document. Uprev to 1.4 |
04/14/21 | Sam Bridger | Final updates before release |
09/15/21 | Jennifer Norris | Added verbiage regarding Rentalman dealers Added the following fields to contract data: starting Odometer and flag to indicate contract is a reservation Made rates optional for contracts Made rates optional for invoices |
6/20/2022 | David Winkel | Added 1.5 release notes Added divisionId field for contracts, including explanation of use Specified valid values for contractType field on contracts Added assetDetail.assetPurchasePrice to support RPO/lease buy-out price if available. Added 1.6 release notes |
4/10/2023 | David Winkel | Add incremental data pull option to pull interface Add real-time update push message option to facilitate immediate updates of offline activities Add real-time integration message options to facilitate digital customer communication via dealer systems Added 2.0 release notes |
6/14/2023 | David Winkel | Complete request integration definitions and samples |
Glossary
RMS
Rental Management System
DCN
Dealer’s Customer Number
DMT
Dealer Management Tool
CWS Login
Caterpillar’s user (identity and authorization) management system managed at login.cat.com
CRS
Caterpillar© Rental Store
UCID
Caterpillar© Universal Customer ID (older Customer ID construct)
Process Overview
Rental Data is a subset of dealer data related to the dealer’s rental business that is retrieved via a pull API for inclusion in the CAT© Rental Store (CRS) suite of web portal, Dealer Management Tool (DMT), Automated Services and customer mobile app. This suite provides access for dealer’s customers to manage information about their rentals and jobsites as well as extend, transfer and end rentals and request service on machines on rent as well as access the dealer’s rental catalog and request rental quotes. It provides access for dealers to manage customer users, publish their catalog and rental rates (base and customer-specific), respond to customer rental requests and other requests by customers such as for service; ending, extending and transferring rented assets; updating the PO number of a contract; registering for access to the CRS portal; and updating the information about a jobsite. It also provides access for non-customers to submit a rental sales lead and for dealers to access and take action on these leads.
Generally speaking, Data is pulled from the dealer at least once per day. This data pull consists of all of the endpoints contained within this document with the exception of the customer endpoint, which is only accessed when a dealer user adds that customer to the DMT to ensure the validity of the Dealer Customer Number (DCN). During this data pull, the dealer locations are refreshed, the base dealer catalog is refreshed, and contracts, invoices and jobsites for all customers the dealer has added to the DMT are refreshed. This data pull is generally timed to run in the early morning hours (local time) of the dealer and be complete before start of business to minimize interference with dealer business operations. In addition, at certain points in the digital interaction with a customer, a partial data pull is performed (such as when a dealer user indicates that action has been taken on a customer request in the DM, such as - End Rental has been scheduled; Service is complete; Transfer Request is complete; Contract extension is complete; Jobsite is updated/created) where data for a specific customer is refreshed immediately to ensure that the most up-to-date information is displayed within the suite.
This data is retrieved from Dealer Rental Management System (RMS) by one of two types of data pull:
Option 1: CAT© Rental Store Dealer Data Pull (described in this document)
This option utilizes API endpoints specified herein that the dealer must build in front of their rental data in order for the Automated Services to collect (pull) and utilize the data within the CAT© Rental Store suite.
Note:In this document, the hostname
rental-api.your-dealer-system.com
is used purely as an example URL root. In practice, this should be substituted for whatever hostname the dealer’s host uses as the root for the APIs that are built.
Option 2: RMS-Specific Dealer Data Pull
This option is not detailed in this document. There may exist other data pull methods where a RMS vendor has entered into a specific agreement with Caterpillar to provide rental-specific data.
Additional Real-Time Integration Functionality
This option is to leverage the CRS Portal and mobile app for the dealer’s rental business by integrating the functionality in such a way that rental customers can see changes in real-time, and dealer staff can manage digital communication with the customers around the rental experience from within the dealer’s RMS or other interfaces. This additional functionality builds on the API options above to include bi-directional messaging between the dealer’s systems and the Cat Rental Store.
Caterpillar Preferred Option
No preference
Related Interfaces
This document covers the interface for pulling rental data from a dealer system into the CAT© Rental Store suite. This data is required for dealers to participate in the suite.
The most recent version of this document (titled CAT© Rental Store Dealer Data Pull Interface) can be referenced at the following link for most up-to-date information:
https://catdealer.com/en/bt/service-operations-strategy/rental/catrentalstore.html
Field Types and Definitions
The following list provides the references to field types that will be used in this document.
Reference | Description | Example |
---|---|---|
Integer | Consists of numeric characters with no spaces, letters or punctuation. | |
Double | Consists of numeric characters with no spaces, letters, or punctuation with the potential presence of a decimal point (.) where appropriate. | |
Datetime | Dates are represented as ISO 8601 strings with both time and timezone elements required. For example: 2019-08-06T00:00:00Z 2019-08-06T12:54:32+04:00 |
|
String | A string is a quoted string encapsulated and escaped with JSON standards. | |
Array | Formatted using JSON standard array notation. [] | |
Object | Formatted using JSON standard object notation. {} | |
Boolean | Represented by the unquoted words true or false. |
Option 1: CAT© Rental Store Dealer Data Pull
Owner | Matt Logan |
---|---|
Author | Jennifer Norris |
For an e-mail address or phone number of the appropriate contact for this interface, please click on the link below.
https://catdealer.com/en/bt/service-operations-strategy/rental/catrentalstore.html
General Comments & Definitions
Comments
The specific types of data that will be pulled are as follows:
- Contract/Asset Data
- Jobsite Data
- Catalog Data
- Invoice Data
- Customer Data
- Dealer Location Data
Error Architecture, Error Codes, and Error Messages
Errors encountered within the implementation of this interface should be returned as failures. There are a couple of exceptions, and cases that are not errors and shouldn’t be returned as errors.
When a server failure happens in the dealer’s API implementation it is important to return that as a server error (5xx) to the caller.
When a request for a list (contract/asset, jobsite, catalog, invoice, dealer location) results in no elements, an empty list should be returned as a success. If the list is empty because of a database failure or other server issue, a server error (5xx) should be returned as a failure. This prevents the CRS services from
The only “successful” case of a 404 response is when a customer looked up via the customer endpoint is not found. In that case, a 404 response should be returned to indicate the customer lookup failed for that customer number.
Security / Authentication considerations
API calls from the CAT© Rental Store Dealer Data Pull Interface useOAuth2.0 authentication using the client credentials authentication flow.
https://www.oauth.com/oauth2-servers/access-tokens/client-credentials/
They will use the standard Authorization: Bearer <access_token>
HTTP header to authenticate requests to the endpoints. Endpoints are required to be encrypted with secure levels of TLS encryption via the https protocol. To configure this, the system will need the following definitions for configuration:
- The client ID used for identifying the data pulls.
- The URL used for retrieving a bearer token for authentication.
- The client secret used to authenticate the client ID when retrieving a bearer token.
- (if chosen, a scope for authentication)
This document presupposes that the endpoints will be fully accessible to the CAT Rental Store services through any dealer firewall. IP addresses for both testing and production elements of the system are available as needed.
Currency Considerations
Currency is a parameter that is specified in the data pull for dealer catalog and is attached to rental rates for a dealer’s catalog. Book rates can be specified as well as individual customer rates.
Regional Considerations
In earlier versions of the API documentation, the assumption was made that dealer territories, and therefore by extension customer jobsites only exist within a single country. However we have added country to both jobsite and dealer location data because there are a number of instances where a dealer territory may span country boundaries.
All times in the APIs are required to be in ISO 8601 format. Dates that do not have a time component should be adjusted in such a way as to make the data consistent regardless of local time of day. (For example, set the time to noon UTC, which corresponds to the international date line.)
Layouts
Layout Comments
None
Contract/Asset Data
The Contract JSON object array is requested with both dealer and customer arguments. However, more than one customer could be included in the returned set of JSON objects, so the RMS customer ID (DCN) should be included in the contract JSON for a single contract so that the returned objects can be differentiated by customer and so that the response data can be superficially validated as being associated with a customer requested. All contracts are collected before any of the customers are updated locally so that they can be updated in bulk, per customer. Up to 5 customer DCNs could be included with the same request to maximize efficiency retrieving these elements without overloading dealer systems with large requests.
Sample endpoint (authentication as specified above, dealer parameter optional if endpoint is dealer-specific):
GET: https://rental-api.your-dealer-system.com/api/v1/contract?customer=dcn1,dcn2,dcn3&items=20&page=0&dealer=X###
Returns pageable interface with an array of active contracts, including nested assets for each contract. This specific request is for all contracts across customers dcn1, dcn2, and dcn3, requesting page 0 (the first page) with 20 items per page. Active contracts are current or future contracts with assets that are, when the request is made, considered to be on-rent at the customer, or are projected to be on-rent with the customer in the future. Note that ‘on-rent’ could also include leased assets, which will be distinguished by the contract type.
Parameters:
Required | Parameter | Type | Description |
---|---|---|---|
false | dealer |
Query | Dealer RMS ID |
true | customer |
Query | Up to 5 Dealer Customer Numbers |
false | items |
Query | Page size (defaults to dealer-specific, we suggest 10) |
false | page |
Query | Page number (default 0 for the first page) |
Return Type
Required | Field | Type | Size/Type Limits | Description | Default | Sample |
---|---|---|---|---|---|---|
true | items |
Array | items | [] | ||
true | items[#] |
Object | A single contract | {} | ||
true | items[#].contractId |
String | varchar(100) | The RMS ID of the contract | A12345 | |
false | items[#].isReservation |
Boolean | Set=True if this contract is a reservation and not an active rental agreement | |||
false | items[#].poNumber |
String | varchar(100) | PO number | PO-12345 | |
false | items[#].paymentType |
String | varchar(20) | Payment type | Check | |
false | items[#].pickupPerson |
String | varchar(100) | Pickup person | Sam Bridger | |
false | items[#].pickupPhone |
String | varchar(100) | Pickup phone | 309-531-7773 | |
false | items[#].salesRep |
String | varchar(100) | Sales representative | Sam Bridger | |
false | items[#].properties |
Object | varchar(>2000) (json data island) | A properties object | {} | |
false | items[#].properties.total |
Double | floating point, please include decimal point for proper conversion | Total | 1234.56 | |
false | items[#].properties.signedBy |
String | Signed by | Sam Bridger | ||
true | items[#].jobsiteId |
String | varchar(200) | The RMS ID of the associated Jobsite | 12345 | |
false | Items[#].divisionId |
String | varchar(255) | The RMS ID of the associated Division | This defaults to the “Rental” division. This is relevant for dealers who wish to split their DMT request management across divisions. In that case, the division IDs need to be coordinated with the Cat Rental Store management tool as any divisionId that does not map to a separate division in the DMT will default to the Rental division. | |
true | items[#].locationId |
String | varchar(255) | The RMS ID of the associated Location | LOCA | |
true | items[#].customerId |
String | varchar(50) | Dealer Customer Number | 00123456 | |
false | items[#].contractType |
String | varchar(100) | Contract type | Rental | This defaults to a “Rental” contract. Other types that are valid: “Lease”: Indicates a lease. “RTO”: Indicates a “Rent To Own” lease. “RPO”: Indicates a “Rental Purchase Option” lease. If the type does not match one of the four above, it will default to Rental. |
true | items[#].contractStartDate |
Datetime | ISO-8601 datetime with timezone | Contract start date | 2019-06-01T12:00:00Z | |
true | items[#].contractEndDate |
Dateime | ISO-8601 datetime with timezone | Contract end date | 2019-06-01T12:00:00Z | |
false | items[#].invoicedThruDate |
Datetime | ISO-8601 datetime with timezone | invoice.billedDateEnd for the most recent periodic invoice on this contract. | ||
false | items[#].invoiceFrequency |
String | Enumerated values | Frequency of invoicing. Enumerated type with possible values to the right defaults to FourWeek if not supplied |
•Day • Week •Month • FourWeek • Quarter • BiWeekly • SemiAnnual • Year • |
|
false | items[#].billControl |
Integer | Days from the start of the billable period after which an invoice is created. | 15 | ||
false | items[#].currency |
String | varchar(10) | Currency of contract | USD or dealers | EUR – defaults to dealer’s default currency. This is primarily for exceptions to the default, though it can always be set. |
false | items[#].pdfUrl |
String | varchar(1000) | URL to retrieve PDF for the contract Should have the same authentication as endpoints, or no authentication requirement. |
https://docs.bridger.com/abcd1234.pdf | |
true | items[#].assetDetails |
Array | Rented asset details objects | [] | ||
true | items[#].assetDetails[#] |
Object | A single asset Detail Object | |||
true | items[#].assetDetails[#].rentedAssetId |
String | varchar(100) | Rented asset Id (rmsId) | 1234567 | |
false | items[#].assetDetails[#].status |
String | Rented asset status | RENT | ||
false | items[#].assetDetails[#].startingOdometer |
String | varchar(100) | Odometer reading at asset start date. | ||
false | items[#].assetDetails[#].attachedTo |
String | varchar(100) | Attached asset RMS Id | 1234567 | |
false | items[#].assetDetails[#].callOffConfirmationNumber |
String | varchar(100) | RMS reference number when an asset is called off (null if not called off) | 1234567 | |
false | items[#].assetDetails[#].assetStartDate |
String | ISO-8601 datetime with timezone | Date asset went on rent on this contract (if null, we assume this matches contract start date) | 2019-06-01T12:00:00Z | |
false | items[#].assetDetails[#].assetCallOffDate |
String | ISO-8601 datetime with timezone | Date asset was called off (null until called off) (can be future) | 2019-06-01T12:00:00Z | |
false | items[#].assetDetails[#].assetReturnedDate |
String | ISO-8601 datetime with timezone | Date asset was returned to dealer (null until returned) | 2019-06-01T12:00:00Z | |
false | items[#].assetDetails[#].itemType |
String | varchar(100) | Item Type | prime | |
true | items[#].assetDetails[#].rentalTotal |
Double | floating point, please include decimal point for proper conversion | Rental total amount | 1234.56 | |
true | items[#].assetDetails[#].quantity |
Integer | Quantity | 1 | ||
false | items[#].assetDetails[#].assetId |
String | varchar(100) | Category Group rms id | 1234567 | |
false | items[#].assetDetails[#].assetName |
String | varchar(100) | Asset name | BACKHOE LOADER, 416 | |
false | items[#].assetDetails[#].longDescription |
String | varchar(>2000) | Long description | 416 4WD Backhoe Loader | |
true | items[#].assetDetails[#].shortDescription |
String | varchar(100) | Short description | 416 | |
false | items[#].assetDetails[#].model |
String | varchar(100) | Equipment model | 416 – if null, uses same value as shortDescrption | |
False | Items[#].assetDetails[#].assetPurchasePrice |
String | varchar(100) | Decimal number for price to purchase the asset that is on rent | This is intended for Rental Purchase Option (or other) leases where the asset has a buy-out price to purchase it. | |
false | items[#].assetDetails[#].rentalRate |
Object | varchar(>2000) (json data island) |
A rentalRate object | ||
false | items[#].assetDetails[#].rentalRate.daily |
Object | A Daily rate object | |||
false | items[#].assetDetails[#].rentalRate.daily.amount |
Integer | Daily amount | 100 | ||
false | items[#].assetDetails[#].rentalRate.daily.currency |
String | Currency | USD | ||
false | items[#].assetDetails[#].rentalRate.daily.display |
String | Display daily amount | 100.00 | ||
false | items[#].assetDetails[#].rentalRate.monthly |
Object | A Monthly rate object | |||
false | items[#].assetDetails[#].rentalRate.monthly.amount |
Integer | Monthly amount | 200 | ||
false | items[#].assetDetails[#].rentalRate.monthly.currency |
String | Currency | USD | ||
false | items[#].assetDetails[#].rentalRate.monthly.display |
String | Display monthly amount | 200.00 | ||
false | items[#].assetDetails[#].rentalRate.weekly |
Object | A Weekly rate object | |||
false | items[#].assetDetails[#].rentalRate.weekly.amount |
Integer | Weekly amount | 150 | ||
false | items[#].assetDetails[#].rentalRate.weekly.currency |
String | Currency | USD | ||
false | items[#].assetDetails[#].rentalRate.weekly.display |
String | Display weekly amount | 150.00 | ||
true | items[#].assetDetails[#].equipmentAssetId |
String | varchar(100) | Equipment asset Id | 1234567 | |
true | items[#].assetDetails[#].manufacturer |
String | varchar(100) | Manufacturer | CATERPILLAR, INC | |
true | items[#].assetDetails[#].serialNumber |
String | varchar(100) | Serial number | 1234567 | |
true | items[#].feeDetails |
Array | feeDetails | [] | ||
true | items[#].feeDetails[#] |
Object | varchar(>2000) (json data island) |
A feeDetails object | {} | |
true | items[#].feeDetails[#].name |
String | Fee details name | Environmental Disposal | ||
true | items[#].feeDetails[#].total |
Double | Fee details total amount | 25.00 | ||
true | items[#].taxDetails |
Array | taxDetails |
[] | Array of tax details for this contract | |
true | items[#].taxDetails[#] |
Object | varchar(>2000) (json data island) |
A taxDetail object | {} | |
true | items[#].taxDetails[#].name |
String | Tax detail name | County Tax | ||
true | items[#].taxDetails[#].total |
Double | Tax detail total amount | 23.23 | ||
true | totalPages |
Integer | Total pages | 1 | ||
true | totalElements |
Integer | Total Elements | 1 | ||
true | empty |
Boolean | Is empty | false | ||
true | size |
Integer | Page size | 20 | ||
true | number |
Integer | Current page number | 0 |
Jobsite Data
The Jobsite JSON object array is requested with both dealer and customer arguments. However, more than one customer could be included in the returned set of JSON objects, so the RMS customer ID (DCN) should be included in the jobsite JSON for a single contract so that the returned objects can be differentiated by customer. All jobsites are collected before any of the customers are updated locally so that they can be updated in bulk, per customer. Up to 5 customer DCNs could be included with the same request.
Sample endpoint (authentication as specified above, dealer parameter optional if endpoint is dealer-specific):
GET:[https://rental-api.your-dealer-system.com/api/v1/jobsite?customer=dcn1,dcn2,dcn3&items=20&page=0&dealer=X###])
Returns pageable interface with an array of active jobsites. This specific request is for all active jobsites across customers dcn1, dcn2, and dcn3, requesting page 0 (the first page) with 20 items per page. An active jobsite does not necessarily have any rented assets associated with it
Parameters
Required | Parameter | Type | Description |
---|---|---|---|
false | dealer |
Query | Dealer rms id. |
true | customer |
Query | Up to 5 DCN. |
false | items |
Query | Page size (defaults to dealer-specific, we suggest 10) |
false | page |
Query | Page number (default 0 for the first page) |
Return Type
Required | Field | Type | Size/Type Limits | Title | Default | Sample |
---|---|---|---|---|---|---|
true | items |
Array | items | [] | ||
true | items[#] |
Object | A single jobsite | {} | ||
true | items[#].jobsiteId |
String | varchar(200) | The RMS ID of the jobsite | 123456 | |
false | items[#].assetCount |
Integer | Asset count for the jobsite | 2 | ||
true | items[#].name |
String | varchar(100) | Jobsite name | I85 Shoring project | |
false | items[#].customerId |
String | varchar(50) | Customer DCN | 1234567 | |
false | items[#].address1 |
String | varchar(200) | Address1 | 123 Any St | |
false | items[#].address2 |
String | varchar(200) | Address2 | Apt 5 | |
false | items[#].city |
String | varchar(100) | City | Atlanta | |
false | items[#].state |
String | varchar(25) | State | GA | |
false | items[#].postalcode |
String | varchar(20) | Postal code | 30309 | |
False | items[#].country |
String | Country | USA | ||
false | items[#].latitude |
String | varchar(20) | Latitude | 01.234567 | |
false | items[#].longitude |
String | varchar(20) | Longitude | 01.234567 | |
false | items[#].firstName |
String | varchar(>2000) (json data island) |
Jobsite Manager First Name | Sam | |
false | items[#].lastName |
String | varchar(>2000) (json data island) | Jobsite Manager Last Name | Bridger | |
false | items[#].phoneNumber |
String | varchar(>2000) (json data island) |
Jobsite Manager Phone Number | 309-531-7773 | |
True | totalPages |
Integer | Total pages | 1 | ||
true | totalElements |
Integer | Total elements | 1 | ||
true | empty |
Boolean | Is empty | false | ||
true | size |
Integer | Page size | 20 | ||
true | number |
Integer | Current page number | 0 |
Catalog Data
The catalog JSON object array is a recursive request for the dealer catalog, including rates specific to a given customer DCN, or if no DCN is supplied, including the book rates for the assets in the dealer catalog. This endpoint only supports requesting one DCN at a time and does not support paging.
Sample endpoint (authentication as specified above):
GET:[https://rental-api.your-dealer-system.com/api/v1/dealer-category?customer=dcn&dealer=X###]
Parameters
Required | Parameter | Type | Description |
---|---|---|---|
false | dealer |
Query | Dealer rms id. |
false | customer |
Query | At most 1 DCN. |
Return Type
Required | Field | Type | Size/Type Limits | Title | Default | Sample |
---|---|---|---|---|---|---|
true | items |
Array | items | [] | ||
true | items[#] |
Object | A single category | {} | ||
true | items[#].categoryId |
String | varchar(100) | The RMS ID of the category | 1234-AERIAL | |
true | items[#].title |
String | varchar(100) | category name | AERIAL | |
true | items[#].categoryGroups |
Array | CategoryGroups | |||
true | items[#].categoryGroups[#] |
Object | A single categoryGroup | {} | ||
true | items[#].categoryGroups[#].title |
String | varchar(100) | Asset name | 40FT BOOM LIFT | |
true | items[#].categoryGroups[#].groupId |
String | varchar(100) | Asset Id | ABL 123 | |
false | items[#].categoryGroups[#].groupRate |
Object | varchar(>2000) (json data island) |
A single groupRate object | {} | |
false | items[#].categoryGroups[#].groupRate.properties |
Object | A single properties object | {} | ||
false | items[#].categoryGroups[#].groupRate.properties.rateType |
String | Rate type | book | ||
false | items[#].categoryGroups[#].groupRate.properties.rentalRateId |
String | Rental Rate rms Id | 1234 | ||
true | items[#].categoryGroups[#].groupRate.properties.daily |
Object | A daily object | {} | ||
false | items[#].categoryGroups[#].groupRate.properties.daily.amount |
Double | Daily amount | 10 | ||
false | items[#].categoryGroups[#].groupRate.properties.daily.currency |
String | Currency | USD | ||
false | items[#].categoryGroups[#].groupRate.properties.daily.display |
String | Display daily amount | 10.00 | ||
true | items[#].categoryGroups[#].groupRate.properties.monthly |
Object | A monthly object | {} | ||
false | items[#].categoryGroups[#].groupRate.properties.monthly.amount |
Double | Monthly amount | 200 | ||
false | items[#].categoryGroups[#].groupRate.properties.monthly.currency |
String | Currency | USD | ||
false | items[#].categoryGroups[#].groupRate.properties.monthly.display |
String | Display monthly amount | 200.00 | ||
true | items[#].categoryGroups[#].groupRate.properties.weekly |
Object | A weekly object | {} | ||
false | items[#].categoryGroups[#].groupRate.properties.weekly.amount |
Double | Weekly amount | 50 | ||
false | items[#].categoryGroups[#].groupRate.properties.weekly.currency |
String | Currency | USD | ||
false | items[#].categoryGroups[#].groupRate.properties.weekly.display |
String | Display weekly amount | 50.00 |
Invoice Data
The Invoice JSON object array is requested with both dealer and customer arguments. Invoices are collected one page at a time to reduce load on dealer systems supplying the invoice data. This endpoint only supports requesting one DCN at a time.
Invoices should be supplied in reverse chronological order (newest first). This is because the data pull will stop when it detects data that it has previously seen.
Sample endpoint (authentication as specified above, dealer parameter optional if endpoint is dealer-specific):
GET:[https://rental-api.your-dealer-system.com/api/v1/invoice?customer=dcn &items=20&page=0&dealer=X###]
Parameters
Required | Parameter | Type | Description |
---|---|---|---|
false | dealer |
Query | Dealer rms id. |
true | customer |
Query | At most 1 DCN. |
false | items |
Query | Page size (defaults to dealer-specific, we suggest 10) |
false | page |
Query | Page number (default 0 for the first page) |
Return Type
Required | Field | Type | Size/Type Limits | Title | Default | Sample |
---|---|---|---|---|---|---|
true | items |
Array | items | [] | ||
true | items[#] |
Object | A single jobsite | {} | ||
true | items[#].invoiceId |
String | varchar(100) | Invoice Number | I1234567 | |
false | items[#].invoiceType |
String | varchar(100) | Invoice Type | Rental | |
false | items[#].poNumber |
String | varchar(100) | PO number | PO-12345 | |
true | items[#].total |
Double | varchar(100) | Invoice total amount | 5000 | |
false | items[#].currency |
String | varchar(10) | Currency of invoice | USD or dealers | EUR – defaults to dealer’s default currency. This is primarily for exceptions to the default, though it can always be set. |
true | items[#].invoiceDate |
Datetime | ISO-8601 datetime with timezone | Invoice date | 2019-07-05T12:00:00Z | |
true | items[#].billedDateStart |
Datetime | ISO-8601 datetime with timezone | Billed start date | 2019-07-05T12:00:00Z | |
true | items[#].billedDateEnd |
Datetime | ISO-8601 datetime with timezone | Billed end date | 2019-07-05T12:00:00Z | |
true | items[#].jobsiteId |
String | varchar(200) | The RMS ID of the associated jobsite | 12345 | |
true | items[#].contractId |
String | varchar(100) | The RMS ID of the associated contract | A1234567 | |
false | items[#].pdfUrl |
String | varchar(1000) | URL to retrieve PDF for the invoice Should have the same authentication as endpoints, or no authentication requiremet. |
https://docs.bridger.com/abcd1234.pdf | |
true | items[#].assetDetails |
Array | varchar(>2000) (json data island) |
Rented asset details objects | [] | Array of up to {assetDetails} asset detail. |
true | items[#].assetDetails[#] |
Object | A single asset Detail Object | {} | ||
true | items[#].assetDetails[#].rentedAssetId |
String | Rented asset Id (rmsId) | 1234567 | ||
true | items[#].assetDetails[#].rentalTotal |
Double | Rental total | 5000 | ||
true | items[#].assetDetails[#].quantity |
Integer | Quantity | 1 | ||
false | items[#].assetDetails[#].assetName |
String | Asset name | BACKHOE LOADER 416 | ||
false | items[#].assetDetails[#].categoryId |
String | Category rms id | 123-BCKHL | ||
false | items[#].assetDetails[#].longDescription |
String | Long description | 416 4WD BACKHOE LOADER | ||
true | items[#].assetDetails[#].shortDescription |
String | Short description | 416 | ||
true | items[#].assetDetails[#].model |
String | varchar(100) | Equipment model | 416 | |
true | items[#].assetDetails[#].equipmentAssetId |
String | Equipment id | EAD123 | ||
true | items[#].assetDetails[#].manufacturer |
String | Manufacturer | CATERPILLAR, INC | ||
true | items[#].assetDetails[#].serialNumber |
String | Serial number | 1234567 | ||
false | items[#].assetDetails[#].rentalRate |
Object | A rentalRate object | |||
false | items[#].assetDetails[#].rentalRate.rateType |
String | Rate type | customer | ||
false | items[#].assetDetails[#].rentalRate.daily |
Object | A daily rate object | |||
false | items[#].assetDetails[#].rentalRate.daily.amout |
Double | Daily Amount | 100 | ||
false | items[#].assetDetails[#].rentalRate.daily.currency |
String | Currency | USD | ||
false | items[#].assetDetails[#].rentalRate.daily.display |
String | Display daily amount | 100.00 | ||
false | items[#].assetDetails[#].rentalRate.monthly |
Object | A monthly rate object | |||
false | items[#].assetDetails[#].rentalRate.monthly.amount |
Double | Monthly amount | 2000 | ||
false | items[#].assetDetails[#].rentalRate.monthly.currency |
String | Currency | USD | ||
false | items[#].assetDetails[#].rentalRate.monthly.display |
String | Display monthly amount | 2000.00 | ||
false | items[#].assetDetails[#].rentalRate.weekly |
Object | A weekly rate object | |||
false | items[#].assetDetails[#].rentalRate.weekly.amount |
Double | Weekly amount | 500 | ||
false | items[#].assetDetails[#].rentalRate.weekly.currency |
String | Currency | USD | ||
false | items[#].assetDetails[#].rentalRate.weekly.display |
String | Display weekly amount | 500.00 | ||
false | items[#].assetDetails[#].rentalRate.rentalRateId |
String | Rental Rate rms ID | Abc123 | ||
true | items[#].feeDetails |
Array | varchar(>2000) (json data island) |
A feeDetails array | [] | |
false | items[#].feeDetails[#] |
Object | {} | |||
true | items[#].feeDetails[#].name |
String | Fee detail name | Environmental Recovery | ||
true | items[#].feeDetails[#].total |
Double | Fee detail total amount | 25.00 | ||
true | items[#].taxDetails |
Array | varchar(>2000) (json data island) |
A taxDetails array | [] | |
false | items[#].taxDetails[#] |
Object | A taxDetails object | {} | ||
true | items[#].taxDetails[#].name |
String | Tax detail name | County Tax | ||
true | items[#].taxDetails[#].total |
Double | Tax detail total amount | 50.00 | ||
true | totalPages |
Integer | Total pages | 1 | ||
true | totalElements |
Integer | Total elements | 1 | ||
true | empty |
Boolean | Is empty | false | ||
true | size |
Integer | Page size | 20 | ||
true | number |
Integer | Current page number | 0 |
Customer Data
This endpoint is utilized to validate a Dealer Customer Number from the dealer’s RMS. If the Dealer Customer Number is not valid, this should return 404 (not found). This endpoint only supports requesting one DCN at a time and does not support paging.
Sample endpoint (authentication as specified above):
GET:[https://rental-api.your-dealer-system.com/api/v1/?customer=dcn&dealer=X###]
Parameters:
Required | Parameter | Type | Description |
---|---|---|---|
true | customer |
Query | Dealer Customer Number |
False | dealer |
Query | Dealer RMS ID |
Return Type
Required | Field | Type | Size/Type Limits | Title | Default | Sample |
---|---|---|---|---|---|---|
true | customer |
Object | A single customer object | {} | ||
true | customer.customerName |
String | varchar(255) | Customer name | BRIDGER, INC | |
true | customer.customerId |
String | varchar(50) | Customer number | 0012345 |
Dealer Location Data
The Location JSON object array is requested with dealer argument.
Sample endpoint (authentication as specified above):
GET:[https://rental-api.your-dealer-system.com/api/v1/location?tems=20&page=0&dealer=X###]
Returns pageable interface with an array of locations. This specific request is for all location associated with the specific dealer requesting page 0 (the first page) with 20 items per page.
Parameters:
Required | Parameter | Type | Description |
---|---|---|---|
false | dealer |
Query | Dealer RMS id. |
false | items |
Query | Page size (defaults to dealer-specific, we suggest 10) |
false | page |
Query | Page number (default 0 for the first page) |
Return Type
Required | Field | Type | Size/Type Limits | Title | Default | Sample |
---|---|---|---|---|---|---|
true | items |
Array | items | [] | ||
true | items[#] |
Object | A single location object | {} | ||
true | items[#].locationId |
String | varchar(255) | The RMS ID of the location | ATL1 | |
false | items[#].properties |
Object | varchar(>2000) (json data island) |
A property object | {} | |
false | items[#].properties.address1 |
String | location address1 | 1230 W Peachtree St | ||
false | items[#].properties.address2 |
String | location address2 | Suite 900 | ||
false | items[#].properties.city |
String | City | Atlanta | ||
false | items[#].properties.state |
String | State | GA | ||
false | items[#].properties.postalcode |
String | Postal Code | 30309 | ||
false | items[#].properties.country |
String | Country | USA | ||
false | items[#].properties.latitude |
String | Latitude | 12.34567 | ||
false | items[#].properties.longitude |
String | Longitude | 12.34567 | ||
false | items[#].properties.name |
String | Location Name | Atlanta Office | ||
true | totalPages |
Integer | Total pages | 1 | ||
true | totalElements |
Integer | Total elements | 1 | ||
true | empty |
Boolean | Is empty | false | ||
true | size |
Integer | Page size | 20 | ||
true | number |
Integer | Current page number | 0 |
Incremental Data Pull
This endpoint is a step toward near-real-time customer data updates without requiring dealer-managed credentials to push updates and change notifications into the CRS Web Services. This adds a simple interface the CRS Web Services can call that will respond with a list of customers who have updated data. That list of customer DCNs will then be filtered for customers that are active in the CRS Web Services, and light-weight customer data pulls will be initiated for DCNs that are both in the list returned, and have users in the CRS Web Services.
This is intended to be an easy step toward real-time push updates and update notifications from the dealer RMS to the CRS Web Services, so an implementation of that would supersede this endpoint. It will be called every 30-60 minutes during the dealer’s business day to update CRS Portal data to reflect changes made in the dealer’s RMS.
The incremental JSON object array is requested with dealer argument and since argument.
Sample endpoint (authentication as specified above):
GET: https://rental-api.your-dealer-system.com/api/v1/incremental>?dealer=X###&since=0000-00-00T00:00:00Z
Returns an array of DCNs with a list of updated information types. This specific request is for all customer numbers that have been updated in the given period.
Parameters:
Required | **Parameter | Type | Description |
---|---|---|---|
false | Dealer |
Query | Dealer RMS id. |
True | Since |
Query | ISO8610 timestamp indicating a request for changes since the given time. |
Return Type
Required | Field | Type | Size/Type Limits | Title | Default | Sample |
---|---|---|---|---|---|---|
true | items |
Array | items | [] | ||
true | items[#] |
Object | A single location object | {} | ||
true | items[#].customerId |
String | varchar(50) | Customer DCN | 1234567 | |
true | items[#].types |
Array | Types | [] | ||
false | Items[#].types[#] |
String | List of types of changes that have occurred with this customer since the date provided | “contract”: indicates a contract has been updated. Triggers jobsite and contract retrieval. “invoice”: indicates invoice changes. Triggers invoice retrieval. “catalog”: indicates catalog rate changes. Triggers catalog retrieval for this DCN. Will not update catalog structure, only rates on the current structure. “document”: indicates pdf updates of contracts of invoices. Triggers document retrieval. |
Transmission/Media Type*
- Mailbox
- Web service
- LU6.2
- XML
- API
- PC to Client
Testing Procedures
Testing Coordination
- Testing requires coordination with the Caterpillar DICE Team.
- Testing can be performed without Caterpillar DICE Team assistance.
- Testing requires coordination with the Caterpillar CRS Team.
Testing Comments
N/A
Who To Contact
For the scheduling of your testing needs, please contact your local dealer Caterpillar CRS Representative to coordinate the needed testing with the appropriate team. If you are unfamiliar with your CRS Representative, you can request assistance from
Test Configuration
N/A
Web Service Interfaces
Web Service URL | Application URL | Comments |
---|---|---|
URL of Web Service |
|
Since the Dealer Data Pull operates on a pull, not a push basis, there is no externally available URL provided to access this interface. |
Sample Test Data
Sample Data Location
Sample JSON data is provided in the DICE SharePoint at the following location:
Production Information
Production Comments
N/A
Production Configuration
Option 2: RMS-Specific Dealer Data Pull
Owner | Dealer RMS Vendor |
---|---|
Author | Sam Bridger |
Specific questions/contact around this option should be directed to the dealer’s specific RMS vendor for Integrated rental dealers. Rentalman dealers should work with their deployment consultant to obtain specifics on how to connect to the CRS portal.
General Comments & Definitions
Comments
This interface is not owned by Caterpillar and questions about this interface should be directed to the specific dealer’s RMS vendor contact which can be provided on request.
Error Architecture, Error Codes, and Error Messages
N/A
Elements, Characteristics, Operator Symbols
N/A
Array Sizes
N/A
Currency Considerations
None
Regional Considerations*
None
Layouts
Layout Comments
Layout provided by RMS vendor when requested
Layout Types
N/A
Security Header format
N/A
Transmission/Media Type
- Mailbox
- Web service
- LU6.2
- XML
- API
- PC to Client
Testing Procedures
Who To Contact
RMS vendor contacts should already be known by a particular dealer.
Test Configuration
N/A
Sample Test Data
N/A
Production Information
Production Comments
N/A
Production Mailbox and Batch ID
N/A
Additional Real-Time Integration Functionality
Owner | Dealer RMS Vendor or Dealer |
---|---|
Author | David Winkel |
Specific questions/contact around this option should be directed to the dealer’s developers or the RMS provider.
General Comments & Definitions
Comments
The intent for this service is to enable both real-time data updates in the Cat Rental Store for customers who are active in the Cat Rental Store, and to enable real-time request integration between a dealer’s rental management system and the Cat Rental Store website. This will, for example, enable off-line transactions to be reflected in real-time on the CRS website, but could also enable automated handling of PO number updates via integrated PO requests submitted to the CRS website, streamlined lead handling in a dealer CRM platform via integrated lead requests from the CRS website, or integrated service request management in the dealer’s rental management system that updates the customer with progress and scheduling even if the service request was not submitted to the CRS website.
What we’re starting out with, with either Option 1 or Option 2, is this:
This state allows the Cat Rental Store services to pull data from the dealer on a daily basis to ensure consistency with dealer data for presentation to customers every day, and to update data during the day based on request completion in the CRS system or other triggers.
Real-time integration adds a bi-directional message passing feature that can be used for more immediate updates of the customer’s view of their rental activities, and more immediate and efficient integration of CRS request processes into the dealer’s own business processes:
Messages that can be passed include updates to customer information, initiation of new requests from either dealer systems or the CRS services, and request updates on active customer requests.
This builds on top of the data pull architecture already in place, and requires that architecture remain in place to work. The messaging facility enables more seamless communication between the dealer’s rental personnel and the customer’s users, for more immediate resolution of questions, problems, and customer requests.
Error Architecture, Error Codes, and Error Messages
Errors are returned in specific cases that will need to be dealt with on the sending side.
There is no error response for an unknown customer associated with a submitted request or messaging message.
Error message for unknown request in response to request update for request not recognized.
Other errors will be sent as messages back to the dealer system. E.g. a bad request update (activity on a request that is closed, etc.) will be sent as a message back to the dealer system. This is to ensure that messages enqueued are handled in the proper order.
Elements, Characteristics, Operator Symbols
N/A
Security / Authentication considerations
API calls from the CAT© Rental Store Dealer Data Pull Interface useOAuth2.0 authentication using the client credentials authentication flow.
https://www.oauth.com/oauth2-servers/access-tokens/client-credentials/
They will use the standard Authorization: Bearer <access_token>
HTTP header to authenticate requests to the endpoints. Endpoints are required to be encrypted with secure levels of TLS encryption via the https protocol. To configure this, the system will need the following definitions for configuration:
The client ID used for identifying the data pulls.
The URL used for retrieving a bearer token for authentication.
The client secret used to authenticate the client ID when retrieving a bearer token.
(if chosen, a scope for authentication)
This authentication can be shared between the above “Option 1” CRS API implementation and real-time integration functionality; however dealer-side credentials will be needed for dealer systems to pass messages to the CRS Web Services. Those credentials will have to be requested from the CRS Web Services team. Separate credentials can be used for test and production systems.
Array Sizes
N/A
Currency Considerations
None
Regional Considerations
None
Layouts
Layout Comments
The message-specific layouts are presented in order of complexity. Less complex models are illustrated before more complex models. The layouts themselves are integrated with the business rules around handling different types of interactions, and those interaction rules are also illustrated with the layouts.
Base Messaging Structure
This adds a messaging endpoint to the CRS API implementation on the dealer side as well:
Sample endpoint (authentication as specified above):
POST:https://rental-api.your-dealer-system.com/api/v1/message?dealer=X###
To keep the message protocol fairly standard, all messages are JSON, and follow the structure:
{ enqueuedTime: <date-time>, // null in submission enqueuedClientId: <clientId used to submit message>, // null in submission attemptTime: <date-time>, // null in submission and submission response attemptCount: <#>, // null in submission, 0 in submission response deliveredTime: <date-time>, // null in submission and submission response active: <boolean>, // null in submission dealerCode: <code>, customerNumber: <dcn>, submittedPriority: <#>, // defaults to 1 if null in submission submittedMessageId: <submittedMessageId>, submittedTime: <date-time>, // ISO8601 timestamp from submitting server messageType: <request|contract|invoice|message|catalog|document>, payload: { errorCode: <error message>, errorSubmittedMessageId: <submittedMessageId>, request: {<request details>}, requestUpdate: {<request update details>}, requestUpdates: [{<request update details>}], message: {<message chain message details>} }}
enqueuedTime
is the time the message entered the queue.
enqueuedClientId
is the client id used to submit the message to the queue. This is pulled from the CurrentUser object when the submission is made, so that it can be matched up to the submitting dealer as additional validation that the submission was from that dealer. If the submission is from an internal source (with the intra-service token), the clientId will be set to “crs-client-id” to indicate it’s an internal message.
deliveredTime
will be maintained by the service, and will be null until the message is delivered. A delivered message is completed and will be deactivated.
dealerCode
will be matched up to dealer.dealerCode within CRS to determine which dealer sourced this message. The dealerCode and enqueuedClientId verify the dealer credentials.
customerNumber
is the affected customer, if relevant. I can be null for request or message types, but is required for contract and invoice types.
submittedPriority
is the submitted priority of the message. In general, a single priority of 1 is envisioned, but a higher priority for request or message messageTypes could be used to enable faster management of more interactive message types.
submittedMessageId
is the calling service’s ID for this message. Can be used in callbacks for status updates or rejection of the message contents.
submittedTime
is the calling service’s message timestamp. This is a potential problem-tracking tool; large variances between the submittedTime, enqueuedTime, and deliveredTime will be problem flags.
messageType
is the type of message. Initially six types are planned:
contract
: Jobsite, contract, and rented asset information should be updated locally for this customer.invoice
: Invoices should be updated locally for this customer.request
: The payload will include a request object and optional requestUpdate object to update a currently active requestsmessage
: The payload will include a message object to add to a currently active message chain.catalog
: Initiate retrieval of catalog rates for the DCN specified.document
: Initiate retrieval of documents (contract, invoice PDFs) for the DCN specified.
payload will be empty or null for contract, invoice, catalog, or document message types, but will include further information for more complicated message types.
When a message is submitted, it is checked for simple validity. This should include checking the dealerCode for validity, check the access credentials (enqueuedClientId matches stored ClientId) to ensure they match the dealerCode given. If it is a request or message type message, it should also be checked for a valid local match to the customerNumber. It’s important to note that customerNumber only needs to be valid for those two message types, for contract, invoice, catalog, and document message types, it’s valid to submit a message with a customerNumber that the services do not have information about. It is then stored. Successful submission response is a replay of the submission with the enqueuedTime and enqueuedClientId fields populated.
Simple Real-Time Update
The JSON required to notify the CRS Web Services of a change in status for a customer is:
{ dealerCode: <code>, customerNumber: <dcn>, submittedMessageId: <submittedMessageId>, submittedTime: <date-time>, // ISO8601 timestamp from submitting server messageType: <contract|invoice|catalog|document>}
This will initiate a data refresh for this customer of the indicated data type. A contract update will also update jobsites.
PO Request Integration
The JSON required to integrate PO updates with the CRS Web Services is:
{ dealerCode: <code>, customerNumber: <dcn>, submittedMessageId: <submittedMessageId>, submittedTime: <date-time>, // ISO8601 timestamp from submitting server messageType: "request", payload: { request: {<request details>}, requestUpdate: {<request update details>} }}
This will include the request details necessary to initiate a request for a message that includes the start of a request, and it will include an update to an existing request (more information from the customer user, an update to cancel the request, etc.) for any message that is intended to indicate progress on a request. PO requests follow this path.
Brown and green text are notifications sent to customer users (brown) or dealer users (green) based on activity on the request. When a request is part of the integration flow, it is assumed that the integrated system on the dealer side will handle dealer-direction notifications, but it is also expected that the dealer-side of the integration will have process points that trigger the notifications that are to be sent to customer users.
Each point where a notification is sent back to the customer user is important to the business logic of the request and is encapsulated in a request update sent back to the CRS Web Services. Any time a customer has an interaction with the request, that interaction will be sent to the dealer system via a message that should be presented with the original request and should generate a notification within the dealer system in whatever way the dealer system notifies users natively which is routed to the appropriate user to handle the update. The structure of an initial request message is as follows:
request: { localId: <alphanumericId>, // the request id in the sending system. remoteId: <alphanumericId>, // For initial submission this will always be null or missing. // For updates remoteId should be populated if known. requestType: "purchase_order", status: "submitted|received|canceled|closed", createdDate: <date>, createdBy: <userSpec>, title: "Purchase Order Request", text: null, // not relevant for PO request requestedDate: null, // not relevant for PO request properties: { currentPoNumber: <Purchase Order "number" as it currently is on the contract>, poNumber: <Purchase Order "number" change requested>, userName: <createdBy user full name> }, contract: { contractNumber: <contractNumber>, contractId: <contractId> }}
If the message is an update and not a request initialization, the request can be simplified for bandwidth, and an update is included:
request: { localId: <alphanumericId>, // the request id in the sending system. remoteId: <alphanumericId>, // For initial submission this will always be null or missing. // For updates remoteId should be populated if known. requestType: "purchase_order", status: "submitted|received|canceled|closed", // request status after this update contract: { contractNumber: <contractNumber>, contractId: <contractId> }},requestUpdate: { status: "submitted|received|canceled|closed", createdDate: <date>, // timestamp for this request update createdBy: <userSpec>, // user who initiated this request update titleToken: <translation token for translation to dealer locale if desired>, titleContent: {}, // a content map of key-value pairs for swapping content into the translated title title: <message title>, // often null, this is based on the status of the request/update text: <message text if any>, // null for many updates, but could have a note attached updateDate: null, // not relevant for PO request properties: { userName: <createdBy user full name> }}
To illustrate both potential interactions and the structure of the message content, a potential path through the process is illustrated here with integration messages.
An initial request, in this case initiated on the CRS portal:
{ dealerCode: "A000", customerNumber: "001234", submittedMessageId: "message1", submittedTime: "2022-01-01T00:00:30Z", messageType: "request", payload: { request: { localId: "1234567", requestType: "purchase_order", status: "submitted", createdDate: "2022-01-01T00:00:30Z", createdBy: "john.customer@customerxyz.com", title: "Purchase Order Request", text: null, properties: { currentPoNumber: "PENDING", poNumber: "PO1234", userName: "John Customer" }, contract: { contractNumber: "C001", contractId: "C001" } } }}
An update message, in this case from the customer to give more information. The request has been stripped of information that is not necessary in an update. That is optional; but the additional information should already be available from the previous message.
{ dealerCode: "A000", customerNumber: "001234", submittedMessageId: "message2", submittedTime: "2022-01-01T00:01:30Z", messageType: "request", payload: { request: { localId: "1234567", remoteId: null, requestType: "purchase_order", status: "submitted", properties: { currentPoNumber: "PENDING", poNumber: "PO1234", }, contract: { contractNumber: "C001", contractId: "C001" } }, requestUpdate: { status: "submitted", createdDate: "2022-01-01T00:01:30Z", createdBy: "john.customer@customerxyz.com", titleToken: "svc-notification-purchase-order-more-info-title", titleContent: { "username":"John Customer", "requestId":"1234567" }, title: "John Customer has sent more info about a purchase order request (1234567)", text: "I need this changed before the next invoice goes out.", properties: { userName: "John Customer" } } }}
An update from the dealer system to the CRS Services indicating someone is working on this. This moves the request from the submitted status to the received status. The text of the update is not used. The update createdBy value should either be a Cat CWS username, or a username preceded by “local:” to indicate it is a username in the local dealer system. The localId and remoteId on the request are flipped (localId is the sending system’s id, remoteId is the id on the receiving system if known) and populated appropriately.
{ dealerCode: "A000", customerNumber: "001234", submittedMessageId: "rmsmessage1", submittedTime: "2022-01-01T00:02:00Z", messageType: "request", payload: { request: { localId: "poreq1", remoteId: "1234567", requestType: "purchase_order", status: "received", properties: { currentPoNumber: "PENDING", poNumber: "PO1234", }, contract: { contractNumber: "C001", contractId: "C001" } }, requestUpdate: { status: "received", createdDate: "2022-01-01T00:01:30Z", createdBy: "local:rentalCoordinator", title: null, text: null, properties: { userName: "Jennifer Rents" } } }}
An update from the dealer system to the CRS Services indicating the change has been made. This moves the request from the received status to the closed status. The text of the update is only used if the dealer user wishes to add a specific note to the customer as part of this update. The update createdBy value should either be a Cat CWS username, or a username preceded by “local:” to indicate it is a username in the local dealer system.
{ dealerCode: "A000", customerNumber: "001234", submittedMessageId: "rmsmessage2", submittedTime: "2022-01-01T00:02:00Z", messageType: "request", payload: { request: { localId: "poreq1", remoteId: "1234567", requestType: "purchase_order", status: "closed", properties: { currentPoNumber: "PENDING", poNumber: "PO1234", }, contract: { contractNumber: "C001", contractId: "C001" } }, requestUpdate: { status: "closed", createdDate: "2022-01-01T00:01:45Z", createdBy: "local:rentalCoordinator", title: null, text: null, properties: { userName: "Jennifer Rents" } } }}
A sample update message, from the CRS Services to the dealer system indicating the customer user would like to cancel the request. This moves the request to the ‘canceled’ status, regardless of where it was previously, unless it was closed. Closed requests cannot be updated any further.
{ dealerCode: "A000", customerNumber: "001234", submittedMessageId: "message3", submittedTime: "2022-01-01T00:01:30Z", messageType: "request", payload: { request: { localId: "1234567", remoteId: "poreq1", requestType: "purchase_order", status: "canceled", properties: { currentPoNumber: "PENDING", poNumber: "PO1234", }, contract: { contractNumber: "C001", contractId: "C001" } }, requestUpdate: { status: "canceled", createdDate: "2022-01-01T00:01:30Z", createdBy: "john.customer@customerxyz.com", titleToken: "svc-notification-purchase-order-cancel-title", titleContent: { "username":"John Customer", "requestId":"1234567" }, title: "John Customer has asked to cancel the purchase order request (1234567)", text: null, properties: { userName: "John Customer" } } }}
An update from the dealer system to the CRS Services indicating the request has been canceled as requested.
{ dealerCode: "A000", customerNumber: "001234", submittedMessageId: "rmsmessage3", submittedTime: "2022-01-01T00:02:00Z", messageType: "request", payload: { request: { localId: "poreq1", remoteId: "1234567", requestType: "purchase_order", status: "closed", properties: { currentPoNumber: "PENDING", poNumber: "PO1234", }, contract: { contractNumber: "C001", contractId: "C001" } }, requestUpdate: { status: "closed", createdDate: "2022-01-01T00:01:45Z", createdBy: "local:rentalCoordinator", title: "Canceled", text: null, properties: { userName: "Jennifer Rents" } } }}
If a request update message for a request is received that is in error but the request details match an existing request (e.g. the request update tries to update a request to received when the request is in the canceled state because the user requested it be canceled), a message indicating an error (via payload.errorCode and payload.errorSubmittedMessageId) will be sent with the full request information and an array called requestUpdates containing every requestUpdate against this request, in order.
{ dealerCode: "A000", customerNumber: "001234", submittedMessageId: "message6", submittedTime: "2022-01-01T00:00:30Z", messageType: "request", payload: { errorCode: "402 Incorrect Update Submitted", errorSubmittedMessageId: "rmsmessage3", request: { localId: "1234567", requestType: "purchase_order", status: "canceled", createdDate: "2022-01-01T00:00:30Z", createdBy: "john.customer@customerxyz.com", title: "Purchase Order Request", text: null, properties: { currentPoNumber: "PENDING", poNumber: "PO1234", userName: "John Customer" }, contract: { contractNumber: "C001", contractId: "C001" } }, requestUpdates: [ { status: "submitted", createdDate: "2022-01-01T00:01:30Z", createdBy: "john.customer@customerxyz.com", titleToken: "svc-notification-purchase-order- more-info-title", titleContent: { "username":"John Customer", "requestId":"1234567" }, title: "John Customer has sent more info about a purchase order request (1234567)", text: "I need this changed before the next invoice goes out.", properties: { userName: "John Customer" } }, { status: "canceled", createdDate: "2022-01-01T00:01:30Z", createdBy: "john.customer@customerxyz.com", titleToken: "svc-notification-purchase-order-cancel-title", titleContent: { "username":"John Customer", "requestId":"1234567" }, title: "John Customer has asked to cancel the purchase order request (1234567)", text: null, properties: { userName: "John Customer" } } ] }}
If the request update was for a request that cannot be located in the CRS Services or the request information does not match the request in the CRS Services, the errorCode will indicate the request was not found in response to the submittedMessageId in errorSubmittedMessageId.
{ dealerCode: "A000", customerNumber: "001234", submittedMessageId: "message6", submittedTime: "2022-01-01T00:00:30Z", messageType: "request", payload: { errorCode: "404 Request Not Found", errorSubmittedMessageId: "rmsmessage3" }}
Jobsite Request Integration
The JSON required to integrate Jobsite updates with the CRS Web Services is:
{ dealerCode: <code>, customerNumber: <dcn>, submittedMessageId: <submittedMessageId>, submittedTime: <date-time>, // ISO8601 timestamp from submitting server messageType: "request", payload: { request: {<request details>}, requestUpdate: {<request update details>} }}
This will include the request details necessary to initiate a request for a message that includes the start of a request, and it will include an update to an existing request (more information from the customer user, an update to cancel the request, etc.) for any message that is intended to indicate progress on a request. Jobsite requests follow this path.
Brown and green text are notifications sent to customer users (brown) or dealer users (green) based on activity on the request. When a request is part of the integration flow, it is assumed that the integrated system on the dealer side will handle dealer-direction notifications, but it is also expected that the dealer-side of the integration will have process points that trigger the notifications that are to be sent to customer users.
Each point where a notification is sent back to the customer user is important to the business logic of the request and is encapsulated in a request update sent back to the CRS Web Services. Any time a customer has an interaction with the request, that interaction will be sent to the dealer system via a message that should be presented with the original request and should generate a notification within the dealer system in whatever way the dealer system notifies users natively which is routed to the appropriate user to handle the update. The structure of an initial Create Jobsite request message payload is as follows:
request: { localId: <alphanumericId>, // the request id in the sending system. remoteId: <alphanumericId>, // For initial submission this will always be null or missing. // For updates remoteId should be populated if known. requestType: "jobsite", status: "submitted", createdDate: <date>, createdBy: <userSpec>, title: "Create Jobsite Request", text: null, // not relevant for jobsite request requestedDate: null, // not relevant for jobsite request properties: { userName: <createdBy user full name>, "jobsiteId":"2273064", "name":"<newname>", "firstName":"<newManagerFirstname>", "lastName":"<newManagerLastname>", "address1":"<newAddress1>", "address2":"<newAddress2>", "city":"<newCity>", "state":"<newST>", "postCode":"<newPostal>", "country":"<newCountry>", "latitude":"<newLatitude>", "longitude":"<newLongitude>", "phoneNumber":"<newPhoneNumber>" }}
The structure of an initial Deactivate Jobsite request message payload is as follows:
request: { localId: <alphanumericId>, // the request id in the sending system. remoteId: <alphanumericId>, // For initial submission this will always be null or missing. // For updates remoteId should be populated if known. requestType: "jobsite", status: "submitted", createdDate: <date>, createdBy: <userSpec>, title: "Deactivate Jobsite Request", text: null, // not relevant for PO request requestedDate: null, // not relevant for PO request properties: { userName: <createdBy user full name>, "jobsiteId":"2273064", "name":"<currentName>", "firstName":"<currentManagerFirstname>", "lastName":"<currentManagerLastname>", "address1":"<currentAddress1>", "address2":"<currentAddress2>", "city":"<currentCity>", "state":"<currentST>", "postCode":"<currentPostal>", "country":"<currentCountry>", "latitude":"<currentLatitude>", "longitude":"<currentLongitude>", "phoneNumber":"<currentPhoneNumber>" }}
The structure of an initial Update Jobsite request message payload is as follows:
If the message is an update and not a request initialization, the request message payload can be simplified for bandwidth, and an update is included:
request: { localId: <alphanumericId>, // the request id in the request: { localId: <alphanumericId>, // the request id in the sending system. remoteId: <alphanumericId>, // For initial submission this will always be null or missing. // For updates remoteId should be populated if known. requestType: "jobsite", status: "submitted|received|canceled|closed" // request status after this update},requestUpdate: { status: "submitted|received|canceled|closed", createdDate: <date>, // timestamp for this request update createdBy: <userSpec>, // user who initiated this request update titleToken: <translation token for translation to dealer locale if desired>, titleContent: {}, // a content map of key-value pairs for swapping content into the translated title title: <message title>, // often null, this is based on the status of the request/update text: <message text if any>, // null for many updates, but could have a note attached updateDate: null, // not relevant for jobsite request properties: { userName: <createdBy user full name> }}
To illustrate both potential interactions and the structure of the message content, a potential path through the process is illustrated here with integration messages.
An initial request, in this case initiated on the CRS portal:
{ dealerCode: "A000", customerNumber: "001234", submittedMessageId: "message1", submittedTime: "2022-01-01T00:00:30Z", messageType: "request", payload: { request: { localId: "1234567", requestType: "jobsite", status: "submitted", createdDate: "2022-01-01T00:00:30Z", createdBy: "john.customer@customerxyz.com", title: "Update Jobsite Request", text: null, properties: { userName: "John Customer", "jobsiteId":"2273064", "name":"ACME Job One", "firstName":"Ronald", "lastName":"Newman", "address1":"1234 Main St", "address2":"", "city":"Franklin", "state":"AK", "postCode":"43567", "country":"", "latitude":"", "longitude":"", "phoneNumber":"+3166666666" }, jobsite: { "jobsiteId":"2273064", "name":"ACME Job One", "firstName":"Carl", "lastName":"Siteman", "address1":"1234 Main St", "address2":"", "city":"Franklin", "state":"AK", "postCode":"43567", "country":"", "latitude":"", "longitude":"", "phoneNumber":"+3155555555" } } }}
An update message, in this case from the customer to give more information. The request has been stripped of information that is not necessary in an update. That is optional; but the additional information should already be available from the previous message.
{ dealerCode: "A000", customerNumber: "001234", submittedMessageId: "message2", submittedTime: "2022-01-01T00:01:30Z", messageType: "request", payload: { request: { localId: "1234567", remoteId: null, requestType: "jobsite", status: "submitted" }, requestUpdate: { status: "submitted", createdDate: "2022-01-01T00:01:30Z", createdBy: "john.customer@customerxyz.com", title: "John Customer has sent more info about a jobsite request (1234567)", text: "I need this changed before the next rental is delivered, Ron Newman is taking over.", properties: { userName: "John Customer" } } }}
An update from the dealer system to the CRS Services indicating someone is working on this. This moves the request from the submitted status to the received status. The text of the update is not used. The update createdBy value should either be a Cat CWS username, or a username preceded by “local:” to indicate it is a username in the local dealer system. The localId and remoteId on the request are flipped (localId is the sending system’s id, remoteId is the id on the receiving system if known) and populated appropriately.
{ dealerCode: "A000", customerNumber: "001234", submittedMessageId: "rmsmessage1", submittedTime: "2022-01-01T00:02:00Z", messageType: "request", payload: { request: { localId: "jobup1", remoteId: "1234567", requestType: "jobsite", status: "received" }, requestUpdate: { status: "received", createdDate: "2022-01-01T00:01:30Z", createdBy: "local:rentalCoordinator", title: null, text: null, properties: { userName: "Jennifer Rents" } } }}
An update from the dealer system to the CRS Services indicating the change has been made. This moves the request from the received status to the closed status. The text of the update is only used if the dealer user wishes to add a specific note to the customer as part of this update. The update createdBy value should either be a Cat CWS username, or a username preceded by “local:” to indicate it is a username in the local dealer system.
{ dealerCode: "A000", customerNumber: "001234", submittedMessageId: "rmsmessage2", submittedTime: "2022-01-01T00:02:00Z", messageType: "request", payload: { request: { localId: "jobup1", remoteId: "1234567", requestType: "jobsite", status: "closed" }, requestUpdate: { status: "closed", createdDate: "2022-01-01T00:01:45Z", createdBy: "local:rentalCoordinator", title: null, text: null, properties: { userName: "Jennifer Rents" } } }}
A sample update message, from the CRS Services to the dealer system indicating the customer user would like to cancel the request. This moves the request to the ‘canceled’ status, regardless of where it was previously, unless it was closed. Closed requests cannot be updated any further.
{ dealerCode: "A000", customerNumber: "001234", submittedMessageId: "message3", submittedTime: "2022-01-01T00:01:30Z", messageType: "request", payload: { request: { localId: "1234567", remoteId: "jobup1", requestType: "jobsite", status: "canceled" }, requestUpdate: { status: "canceled", createdDate: "2022-01-01T00:01:30Z", createdBy: "john.customer@customerxyz.com", title: "John Customer has asked to cancel the jobsite request (1234567)", text: null, properties: { userName: "John Customer" } } }}
An update from the dealer system to the CRS Services indicating the request has been canceled as requested.
{ dealerCode: "A000", customerNumber: "001234", submittedMessageId: "rmsmessage3", submittedTime: "2022-01-01T00:02:00Z", messageType: "request", payload: { request: { localId: "jobup1", remoteId: "1234567", requestType: "jobsite", status: "closed" }, requestUpdate: { status: "closed", createdDate: "2022-01-01T00:01:45Z", createdBy: "local:rentalCoordinator", title: "Canceled", text: null, properties: { userName: "Jennifer Rents" } } }}
Transfer Request Integration
The JSON required to integrate Transfer updates with the CRS Web Services is:
{ dealerCode: <code>, customerNumber: <dcn>, submittedMessageId: <submittedMessageId>, submittedTime: <date-time>, // ISO8601 timestamp from submitting server messageType: "request", payload: { request: {<request details>}, requestUpdate: {<request update details>} }}
This will include the request details necessary to initiate a request for a message that includes the start of a request, and it will include an update to an existing request (more information from the customer user, an update to cancel the request, etc.) for any message that is intended to indicate progress on a request. Transfer requests follow this path.
Brown and green text are notifications sent to customer users (brown) or dealer users (green) based on activity on the request. When a request is part of the integration flow, it is assumed that the integrated system on the dealer side will handle dealer-direction notifications, but it is also expected that the dealer-side of the integration will have process points that trigger the notifications that are to be sent to customer users.
Each point where a notification is sent back to the customer user is important to the business logic of the request and is encapsulated in a request update sent back to the CRS Web Services. Any time a customer has an interaction with the request, that interaction will be sent to the dealer system via a message that should be presented with the original request and should generate a notification within the dealer system in whatever way the dealer system notifies users natively which is routed to the appropriate user to handle the update. Three additional properties are included in the payload of a transfer request; the customer can indicate the preferred transfer date with the requestedDate field, the customer can indicate whether they need transportation provided by the dealer with the transportationNeeded flag, and the customer can indicate that the PO number for assets being transferred should be changed when the transfer happens with a poNumber field. The structure of an initial Transfer request message payload is as follows:
request: { localId: <alphanumericId>, // the request id in the sending system. remoteId: <alphanumericId>, // For initial submission this will always be null or missing. // For updates remoteId should be populated if known. requestType: "transfer", status: "submitted", createdDate: <date>, createdBy: <userSpec>, title: "Transfer Request", text: null, // not relevant for transfer request requestedDate: "2023-01-01T00:00:00Z", properties: { userName: <createdBy user full name>, "jobsiteId":"2273064", "transportationNeeded":false, "poNumber":"PO102", "name":"<newname>", "firstName":"<newManagerFirstname>", "lastName":"<newManagerLastname>", "address1":"<newAddress1>", "address2":"<newAddress2>", "city":"<newCity>", "state":"<newST>", "postCode":"<newPostal>", "country":"<newCountry>", "latitude":"<newLatitude>", "longitude":"<newLongitude>", "phoneNumber":"<newPhoneNumber>" }, "assets": [ { "rentedAssetId":"34567", "equipmentAssetId":"23456", "serialNumber":"12345" } ]}
If the message is an update and not a request initialization, the request message payload can be simplified for bandwidth, and an update is included:
request: { localId: <alphanumericId>, // the request id in the sending system. remoteId: <alphanumericId>, // For updates remoteId should be populated if known. requestType: "transfer", status: "submitted|received|scheduled|canceled|closed" // request status after this update},requestUpdate: { status: "submitted|received|scheduled|canceled|closed", createdDate: <date>, // timestamp for this request update createdBy: <userSpec>, // user who initiated this request update titleToken: <translation token for translation to dealer locale if desired>, titleContent: {}, // a content map of key-value pairs for swapping content into the translated title title: <message title>, // often null, this is based on the status of the request/update text: <message text if any>, // null for many updates, but could have a note attached updateDate: <scheduled date or new requested date, if any>, properties: { userName: <createdBy user full name> }}
To illustrate both potential interactions and the structure of the message content, a potential path through the process is illustrated here with integration messages.
An initial request, in this case initiated on the CRS portal, affecting two assets:
{ dealerCode: "A000", customerNumber: "001234", submittedMessageId: "message1", submittedTime: "2022-01-01T00:00:30Z", messageType: "request", payload: { request: { localId: "1234567", requestType: "transfer", status: "submitted", createdDate: "2022-01-01T00:00:30Z", createdBy: "john.customer@customerxyz.com", title: "Transfer Request", text: null, requestedDate: "2022-01-03T16:00:00Z", properties: { userName: "John Customer", "jobsiteId":"2273064", "transportationNeeded":false, "poNumber":"PO102", "name":"ACME Job One", "firstName":"Ronald", "lastName":"Newman", "address1":"1234 Main St", "address2":"", "city":"Franklin", "state":"AK", "postCode":"43567", "country":"", "latitude":"", "longitude":"", "phoneNumber":"+3166666666" }, assets: [ { "rentedAssetId":"34567", "equipmentAssetId":"23456", "serialNumber":"12345" }, { "rentedAssetId":"34568", "equipmentAssetId":"23457", "serialNumber":"12346" } ] } }}
An update message, in this case from the customer to give more information. The request has been stripped of information that is not necessary in an update. That is optional; but the additional information should already be available from the previous message.
{ dealerCode: "A000", customerNumber: "001234", submittedMessageId: "message2", submittedTime: "2022-01-01T00:01:30Z", messageType: "request", payload: { request: { localId: "1234567", remoteId: null, requestType: "transfer", status: "submitted" }, requestUpdate: { status: "submitted", createdDate: "2022-01-01T00:01:30Z", createdBy: "john.customer@customerxyz.com", title: "John Customer has sent more info about a transfer request (1234567)", text: "I need this moved as soon as possible. Holes won’t dig themselves.", properties: { userName: "John Customer" } } }}
An update from the dealer system to the CRS Services indicating someone is working on this. This moves the request from the submitted status to the received status. The text of the update is not used. The update createdBy value should either be a Cat CWS username, or a username preceded by “local:” to indicate it is a username in the local dealer system. The localId and remoteId on the request are flipped (localId is the sending system’s id, remoteId is the id on the receiving system if known) and populated appropriately.
{ dealerCode: "A000", customerNumber: "001234", submittedMessageId: "rmsmessage1", submittedTime: "2022-01-01T00:02:00Z", messageType: "request", payload: { request: { localId: "trans1", remoteId: "1234567", requestType: "transfer", status: "received" }, requestUpdate: { status: "received", createdDate: "2022-01-01T00:01:30Z", createdBy: "local:rentalCoordinator", title: null, text: null, properties: { userName: "Jennifer Rents" } } }}
An update from the dealer system to the CRS Services indicating the request has been scheduled. This moves the request from the received status to the scheduled status. The text of the update is only used if the dealer user wishes to add a specific note to the customer as part of this update. The update createdBy value should either be a Cat CWS username, or a username preceded by “local:” to indicate it is a username in the local dealer system. While not explicitly enforced in the API, if transportationNeeded is set to true on the request, the date the transfer is scheduled should be included as a property of the update (updateDate), as this indicates to the customer when transportation has been scheduled.
{ dealerCode: "A000", customerNumber: "001234", submittedMessageId: "rmsmessage2", submittedTime: "2022-01-01T00:02:00Z", messageType: "request", payload: { request: { localId: "trans1", remoteId: "1234567", requestType: "transfer", status: "scheduled" }, requestUpdate: { status: "scheduled", createdDate: "2022-01-01T00:01:45Z", createdBy: "local:rentalCoordinator", title: null, text: null, updateDate: "2022-01-03T16:00:00Z" properties: { userName: "Jennifer Rents", } } }}
Finally, once the transfer has been completed, an update from the dealer system to the CRS Services indicating the request has been closed as requested.
{ dealerCode: "A000", customerNumber: "001234", submittedMessageId: "rmsmessage3", submittedTime: "2022-01-03T16:40:00Z", messageType: "request", payload: { request: { localId: "trans1", remoteId: "1234567", requestType: "transfer", status: "closed" }, requestUpdate: { status: "closed", createdDate: "2022-01-01T00:01:45Z", createdBy: "local:rentalCoordinator", title: null, text: null, properties: { userName: "Jennifer Rents" } } }}
A sample update message, from the CRS Services to the dealer system indicating the customer user would like to cancel the request. This moves the request to the ‘canceled’ status, regardless of where it was previously, unless it was closed. Closed requests cannot be updated any further.
{ dealerCode: "A000", customerNumber: "001234", submittedMessageId: "message3", submittedTime: "2022-01-01T00:01:30Z", messageType: "request", payload: { request: { localId: "1234567", remoteId: "trans1", requestType: "transfer", status: "canceled" }, requestUpdate: { status: "canceled", createdDate: "2022-01-01T00:01:30Z", createdBy: "john.customer@customerxyz.com", title: "John Customer has asked to cancel the transfer request (1234567)", text: null, properties: { userName: "John Customer" } } }}
An update from the dealer system to the CRS Services indicating the request has been canceled as requested.
{ dealerCode: "A000", customerNumber: "001234", submittedMessageId: "rmsmessage3", submittedTime: "2022-01-01T00:02:00Z", messageType: "request", payload: { request: { localId: "trans1", remoteId: "1234567", requestType: "transfer", status: "closed" }, requestUpdate: { status: "closed", createdDate: "2022-01-01T00:01:45Z", createdBy: "local:rentalCoordinator", title: "Canceled", text: null, properties: { userName: "Jennifer Rents" } } }}
Extend Request Integration
The JSON required to integrate extend requests with the CRS Web Services is:
{ dealerCode: <code>, customerNumber: <dcn>, submittedMessageId: <submittedMessageId>, submittedTime: <date-time>, // ISO8601 timestamp from submitting server messageType: "request", payload: { request: {<request details>}, requestUpdate: {<request update details>} }}
This will include the request details necessary to initiate a request for a message that includes the start of a request, and it will include an update to an existing request (more information from the customer user, an update to cancel the request, etc.) for any message that is intended to indicate progress on a request. Extend requests follow this path.
Brown and green text are notifications sent to customer users (brown) or dealer users (green) based on activity on the request. When a request is part of the integration flow, it is assumed that the integrated system on the dealer side will handle dealer-direction notifications, but it is also expected that the dealer-side of the integration will have process points that trigger the notifications that are to be sent to customer users.
Each point where a notification is sent back to the customer user is important to the business logic of the request and is encapsulated in a request update sent back to the CRS Web Services. Any time a customer has an interaction with the request, that interaction will be sent to the dealer system via a message that should be presented with the original request and should generate a notification within the dealer system in whatever way the dealer system notifies users natively which is routed to the appropriate user to handle the update. The structure of an initial request message is as follows:
request: { localId: <alphanumericId>, // the request id in the sending system. remoteId: <alphanumericId>, // For initial submission this will always be null or missing. // For updates remoteId should be populated if known. requestType: "extend", status: "submitted|received|canceled|closed", createdDate: <date>, createdBy: <userSpec>, title: "Extend Request", text: "<customer may supply information with the request>", requestedDate: <date>, // new estimated end date for contracts associated with the assets. properties: { userName: <createdBy user full name> }, "assets": [ { "rentedAssetId":"34567", "equipmentAssetId":"23456", "serialNumber":"12345" } ]}
If the message is an update and not a request initialization, the request can be simplified for bandwidth, and an update is included:
request: { localId: <alphanumericId>, // the request id in the sending system. remoteId: <alphanumericId>, // For initial submission this will always be null or missing. // For updates remoteId should be populated if known. requestType: "extend", status: "submitted|received|canceled|closed" // request status after this update},requestUpdate: { status: "submitted|received|canceled|closed", createdDate: <date>, // timestamp for this request update createdBy: <userSpec>, // user who initiated this request update titleToken: <translation token for translation to dealer locale if desired>, titleContent: {}, // a content map of key-value pairs for swapping content into the translated title title: <message title>, // often null, this is based on the status of the request/update text: <message text if any>, // null for many updates, but could have a note attached updateDate: null, // may be updated with new estimated end date for assets if necessary properties: { userName: <createdBy user full name> }}
To illustrate both potential interactions and the structure of the message content, a potential path through the process is illustrated here with integration messages.
An initial request, in this case initiated on the CRS portal:
{ dealerCode: "A000", customerNumber: "001234", submittedMessageId: "message1", submittedTime: "2022-01-01T00:00:30Z", messageType: "request", payload: { request: { localId: "1234567", requestType: "extend", status: "submitted", createdDate: "2022-01-01T00:00:30Z", createdBy: "john.customer@customerxyz.com", title: "Extend Request", requestedDate: "2022-06-01T00:00:30Z", text: null, properties: { userName: "John Customer" }, assets: [ { "rentedAssetId":"34567", "equipmentAssetId":"23456", "serialNumber":"12345" }, { "rentedAssetId":"34568", "equipmentAssetId":"23457", "serialNumber":"12346" } ] } }}
An update message, in this case from the customer to give more information. The request has been stripped of information that is not necessary in an update. That is optional; but the additional information should already be available from the previous message.
{ dealerCode: "A000", customerNumber: "001234", submittedMessageId: "message2", submittedTime: "2022-01-01T00:01:30Z", messageType: "request", payload: { request: { localId: "1234567", remoteId: null, requestType: "extend", status: "submitted" }, requestUpdate: { status: "submitted", createdDate: "2022-01-01T00:01:30Z", createdBy: "john.customer@customerxyz.com", title: "John Customer has sent more info about an extend request (1234567)", text: "We’re going to need these for another 6 months.", properties: { userName: "John Customer" } } }}
An update from the dealer system to the CRS Services indicating someone is working on this. This moves the request from the submitted status to the received status. The text of the update is not used. The update createdBy value should either be a Cat CWS username, or a username preceded by “local:” to indicate it is a username in the local dealer system. The localId and remoteId on the request are flipped (localId is the sending system’s id, remoteId is the id on the receiving system if known) and populated appropriately.
{ dealerCode: "A000", customerNumber: "001234", submittedMessageId: "rmsmessage1", submittedTime: "2022-01-01T00:02:00Z", messageType: "request", payload: { request: { localId: "extend1", remoteId: "1234567", requestType: "extend", status: "received" }, requestUpdate: { status: "received", createdDate: "2022-01-01T00:01:30Z", createdBy: "local:rentalCoordinator", title: null, text: null, properties: { userName: "Jennifer Rents" } } }}
An update from the dealer system to the CRS Services indicating the change has been made. This moves the request from the received status to the closed status. The text of the update is only used if the dealer user wishes to add a specific note to the customer as part of this update. The update createdBy value should either be a Cat CWS username, or a username preceded by “local:” to indicate it is a username in the local dealer system.
{ dealerCode: "A000", customerNumber: "001234", submittedMessageId: "rmsmessage2", submittedTime: "2022-01-01T00:02:00Z", messageType: "request", payload: { request: { localId: "extend1", remoteId: "1234567", requestType: "extend", status: "closed" }, requestUpdate: { status: "closed", createdDate: "2022-01-01T00:01:45Z", createdBy: "local:rentalCoordinator", title: null, text: null, properties: { userName: "Jennifer Rents" } } }}
A sample update message, from the CRS Services to the dealer system indicating the customer user would like to cancel the request. This moves the request to the ‘canceled’ status, regardless of where it was previously, unless it was closed. Closed requests cannot be updated any further.
{ dealerCode: "A000", customerNumber: "001234", submittedMessageId: "message3", submittedTime: "2022-01-01T00:01:30Z", messageType: "request", payload: { request: { localId: "1234567", remoteId: "extend1", requestType: "extend", status: "canceled" }, requestUpdate: { status: "canceled", createdDate: "2022-01-01T00:01:30Z", createdBy: "john.customer@customerxyz.com", title: "John Customer has asked to cancel the extend request (1234567)", text: null, properties: { userName: "John Customer" } } }}
An update from the dealer system to the CRS Services indicating the request has been canceled as requested.
{ dealerCode: "A000", customerNumber: "001234", submittedMessageId: "rmsmessage3", submittedTime: "2022-01-01T00:02:00Z", messageType: "request", payload: { request: { localId: "extend1", remoteId: "1234567", requestType: "extend", status: "closed" }, requestUpdate: { status: "closed", createdDate: "2022-01-01T00:01:45Z", createdBy: "local:rentalCoordinator", title: "Canceled", text: null, properties: { userName: "Jennifer Rents" } } }}
Call-off or End Request Integration
The JSON required to integrate Call-off updates with the CRS Web Services is:
{ dealerCode: <code>, customerNumber: <dcn>, submittedMessageId: <submittedMessageId>, submittedTime: <date-time>, // ISO8601 timestamp from submitting server messageType: "request", payload: { request: {<request details>}, requestUpdate: {<request update details>} }}
This will include the request details necessary to initiate a request for a message that includes the start of a request, and it will include an update to an existing request (more information from the customer user, an update to cancel the request, etc.) for any message that is intended to indicate progress on a request. Call-off requests follow this path.
Brown and green text are notifications sent to customer users (brown) or dealer users (green) based on activity on the request. When a request is part of the integration flow, it is assumed that the integrated system on the dealer side will handle dealer-direction notifications, but it is also expected that the dealer-side of the integration will have process points that trigger the notifications that are to be sent to customer users.
Each point where a notification is sent back to the customer user is important to the business logic of the request and is encapsulated in a request update sent back to the CRS Web Services. Any time a customer has an interaction with the request, that interaction will be sent to the dealer system via a message that should be presented with the original request and should generate a notification within the dealer system in whatever way the dealer system notifies users natively which is routed to the appropriate user to handle the update. Two additional properties are included in the payload of a call-off request; the customer can indicate the preferred call-off date with the requestedDate field and the customer can indicate whether they need transportation provided by the dealer with the transportationNeeded flag. The structure of an initial Call-off request message payload is as follows:
request: { localId: <alphanumericId>, // the request id in the sending system. remoteId: <alphanumericId>, // For initial submission this will always be null or missing. // For updates remoteId should be populated if known. requestType: "calloff", status: "submitted", createdDate: <date>, createdBy: <userSpec>, title: "Call-off Request", text: null, // not relevant for transfer request requestedDate: "2023-01-01T00:00:00Z", properties: { userName: <createdBy user full name>, "transportationNeeded":false }, "assets": [ { "rentedAssetId":"34567", "equipmentAssetId":"23456", "serialNumber":"12345" } ]}
If the message is an update and not a request initialization, the request message payload can be simplified for bandwidth, and an update is included:
request: { localId: <alphanumericId>, // the request id in the sending system. remoteId: <alphanumericId>, // For updates remoteId should be populated if known. requestType: "calloff", status: "submitted|received|scheduled|canceled|closed" // request status after this update},requestUpdate: { status: "submitted|received|scheduled|canceled|closed", createdDate: <date>, // timestamp for this request update createdBy: <userSpec>, // user who initiated this request update titleToken: <translation token for translation to dealer locale if desired>, titleContent: {}, // a content map of key-value pairs for swapping content into the translated title title: <message title>, // often null, this is based on the status of the request/update text: <message text if any>, // null for many updates, but could have a note attached updateDate: <scheduled date or new requested date, if any>, properties: { userName: <createdBy user full name> }}
To illustrate both potential interactions and the structure of the message content, a potential path through the process is illustrated here with integration messages.
An initial request, in this case initiated on the CRS portal, affecting two assets:
{ dealerCode: "A000", customerNumber: "001234", submittedMessageId: "message1", submittedTime: "2022-01-01T00:00:30Z", messageType: "request", payload: { request: { localId: "1234567", requestType: "calloff", status: "submitted", createdDate: "2022-01-01T00:00:30Z", createdBy: "john.customer@customerxyz.com", title: "Call-off Request", text: null, requestedDate: "2022-01-03T16:00:00Z", properties: { userName: "John Customer", "jobsiteId":"2273064", "transportationNeeded":false }, assets: [ { "rentedAssetId":"34567", "equipmentAssetId":"23456", "serialNumber":"12345" }, { "rentedAssetId":"34568", "equipmentAssetId":"23457", "serialNumber":"12346" } ] } }}
An update message, in this case from the customer to give more information. The request has been stripped of information that is not necessary in an update. That is optional; but the additional information should already be available from the previous message.
{ dealerCode: "A000", customerNumber: "001234", submittedMessageId: "message2", submittedTime: "2022-01-01T00:01:30Z", messageType: "request", payload: { request: { localId: "1234567", remoteId: null, requestType: "calloff", status: "submitted" }, requestUpdate: { status: "submitted", createdDate: "2022-01-01T00:01:30Z", createdBy: "john.customer@customerxyz.com", title: "John Customer has sent more info about an end rental request (1234567)", text: "I need this removed as soon as possible. The holes are dug.", properties: { userName: "John Customer" } } }}
An update from the dealer system to the CRS Services indicating someone is working on this. This moves the request from the submitted status to the received status. The text of the update is not used. The update createdBy value should either be a Cat CWS username, or a username preceded by “local:” to indicate it is a username in the local dealer system. The localId and remoteId on the request are flipped (localId is the sending system’s id, remoteId is the id on the receiving system if known) and populated appropriately.
{ dealerCode: "A000", customerNumber: "001234", submittedMessageId: "rmsmessage1", submittedTime: "2022-01-01T00:02:00Z", messageType: "request", payload: { request: { localId: "end1", remoteId: "1234567", requestType: "calloff", status: "received" }, requestUpdate: { status: "received", createdDate: "2022-01-01T00:01:30Z", createdBy: "local:rentalCoordinator", title: null, text: null, properties: { userName: "Jennifer Rents" } } }}
An update from the dealer system to the CRS Services indicating the request has been scheduled. This moves the request from the received status to the scheduled status. The text of the update is only used if the dealer user wishes to add a specific note to the customer as part of this update. The update createdBy value should either be a Cat CWS username, or a username preceded by “local:” to indicate it is a username in the local dealer system. If transportationNeeded is set to true on the request, the date of the pickup is scheduled separately by the dealer, the property of the update (updateDate) is the scheduled date of the end of the contract, not the pickup date.
{ dealerCode: "A000", customerNumber: "001234", submittedMessageId: "rmsmessage2", submittedTime: "2022-01-01T00:02:00Z", messageType: "request", payload: { request: { localId: "end1", remoteId: "1234567", requestType: "calloff", status: "scheduled" }, requestUpdate: { status: "scheduled", createdDate: "2022-01-01T00:01:45Z", createdBy: "local:rentalCoordinator", title: null, text: null, updateDate: "2022-01-03T16:00:00Z" properties: { userName: "Jennifer Rents", } } }}
It is not necessary to close end rental requests unless they are cancelled by the customer or by the dealer. End rental requests are automatically closed when the contract is no longer active. However, if preferred, once the calloff has been completed, an update from the dealer system can be made to the CRS Services indicating the request has been closed as requested.
{ dealerCode: "A000", customerNumber: "001234", submittedMessageId: "rmsmessage3", submittedTime: "2022-01-03T16:40:00Z", messageType: "request", payload: { request: { localId: "end1", remoteId: "1234567", requestType: "calloff", status: "closed" }, requestUpdate: { status: "closed", createdDate: "2022-01-01T00:01:45Z", createdBy: "local:rentalCoordinator", title: null, text: null, properties: { userName: "Jennifer Rents" } } }} ```A sample update message, from the CRS Services to the dealer system indicating the customer user would like to cancel the request. This moves the request to the ‘canceled’ status, regardless of where it was previously, unless it was closed. Closed requests cannot be updated any further.```json{ dealerCode: "A000", customerNumber: "001234", submittedMessageId: "message3", submittedTime: "2022-01-01T00:01:30Z", messageType: "request", payload: { request: { localId: "1234567", remoteId: "end1", requestType: "calloff", status: "canceled" }, requestUpdate: { status: "canceled", createdDate: "2022-01-01T00:01:30Z", createdBy: "john.customer@customerxyz.com", title: "John Customer has asked to cancel the end rental request (1234567)", text: null, properties: { userName: "John Customer" } } }}
An update from the dealer system to the CRS Services indicating the request has been canceled as requested.
{ dealerCode: "A000", customerNumber: "001234", submittedMessageId: "rmsmessage3", submittedTime: "2022-01-01T00:02:00Z", messageType: "request", payload: { request: { localId: "end1", remoteId: "1234567", requestType: "calloff", status: "closed" }, requestUpdate: { status: "closed", createdDate: "2022-01-01T00:01:45Z", createdBy: "local:rentalCoordinator", title: "Canceled", text: null, properties: { userName: "Jennifer Rents" } } }}
Service Request Integration
The JSON required to integrate Service updates with the CRS Web Services is:
{ dealerCode: <code>, customerNumber: <dcn>, submittedMessageId: <submittedMessageId>, submittedTime: <date-time>, // ISO8601 timestamp from submitting server messageType: "request", payload: { request: {<request details>}, requestUpdate: {<request update details>} }}
This will include the request details necessary to initiate a request for a message that includes the start of a request, and it will include an update to an existing request (more information from the customer user, an update to cancel the request, etc.) for any message that is intended to indicate progress on a request. Service requests follow this path.
Brown and green text are notifications sent to customer users (brown) or dealer users (green) based on activity on the request. When a request is part of the integration flow, it is assumed that the integrated system on the dealer side will handle dealer-direction notifications, but it is also expected that the dealer-side of the integration will have process points that trigger the notifications that are to be sent to customer users.
Each point where a notification is sent back to the customer user is important to the business logic of the request and is encapsulated in a request update sent back to the CRS Web Services. Any time a customer has an interaction with the request, that interaction will be sent to the dealer system via a message that should be presented with the original request and should generate a notification within the dealer system in whatever way the dealer system notifies users natively which is routed to the appropriate user to handle the update. Two additional properties are included in the payload of a service request; the customer can indicate whether the asset is still operational despite requiring service with the isWorking flag and the customer can attach photos to the request to illustrate issues with the equipment with the images array. Request updates can update the isWorking flag to indicate a change in the status of the asset, have additional attached images in an images array, and support scheduling service between the dealer and customer with the updateDate field. While a service request uses the same assets array on the request as some other request types, a service request is limited to one asset in the array. The structure of an initial Service request message payload is as follows:
request: { localId: <alphanumericId>, // the request id in the sending system. remoteId: <alphanumericId>, // For initial submission this will always be null or missing. // For updates remoteId should be populated if known. requestType: "service", status: "submitted", createdDate: <date>, createdBy: <userSpec>, title: "Service Request", text: null, // can be populated for service request requestedDate: null, properties: { userName: <createdBy user full name>, isWorking: true, images:[] }, "assets": [ { "rentedAssetId":"34567", "equipmentAssetId":"23456", "serialNumber":"12345" } ]}
If the message is an update and not a request initialization, the request message payload can be simplified for bandwidth, and an update is included:
request: { localId: <alphanumericId>, // the request id in the sending system. remoteId: <alphanumericId>, // For updates remoteId should be populated if known. requestType: "service", status: "submitted|received|scheduled|canceled|closed" // request status after this update},requestUpdate: { status: "submitted|received|scheduled|canceled|closed", createdDate: <date>, // timestamp for this request update createdBy: <userSpec>, // user who initiated this request update titleToken: <translation token for translation to dealer locale if desired>, titleContent: {}, // a content map of key-value pairs for swapping content into the translated title title: <message title>, // often null, this is based on the status of the request/update text: <message text if any>, // null for many updates, but could have a note attached updateDate: <scheduled date, if any>, properties: { userName: <createdBy user full name>, isWorking: true, images:[] }}
The structure of an attached image (or other attached file) is as follows:
{ filename: "filename.ext", mimetype: "mime/type", contents: "<base64-encoded contents of the binary file>"}
To illustrate both potential interactions and the structure of the message content, a potential path through the process is illustrated here with integration messages.
An initial request, in this case initiated on the CRS portal:
{ dealerCode: "A000", customerNumber: "001234", submittedMessageId: "message1", submittedTime: "2022-01-01T00:00:30Z", messageType: "request", payload: { request: { localId: "1234567", requestType: "service", status: "submitted", createdDate: "2022-01-01T00:00:30Z", createdBy: "john.customer@customerxyz.com", title: "Service Request", text: "The machine won’t start. Can’t dig without a working digger.", requestedDate: null, properties: { userName: "John Customer", "isWorking":true, "images":[] }, assets: [ { "rentedAssetId":"34567", "equipmentAssetId":"23456", "serialNumber":"12345" } ] } }}
An update message, in this case from the customer to give more information. The request has been stripped of information that is not necessary in an update. That is optional; but the additional information should already be available from the previous message.
{ dealerCode: "A000", customerNumber: "001234", submittedMessageId: "message2", submittedTime: "2022-01-01T00:01:30Z", messageType: "request", payload: { request: { localId: "1234567", remoteId: null, requestType: "service", status: "submitted" }, requestUpdate: { status: "submitted", createdDate: "2022-01-01T00:01:30Z", createdBy: "john.customer@customerxyz.com", title: "John Customer has sent more info about a service request (1234567)", text: "I added a picture and noted that the machine is not working.", properties: { userName: "John Customer", "isWorking":false, "images":[ { filename:"image.jpg", mimetype:"image/jpeg", contents:"/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQ ERMUFRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT/wAARCABLAEsDAREAAhEBAxEB/8QAHAABAAIDAQEBAAAAAAAAAAAAAAYHAwgJBQIE/8QANBAAAQMEAQMCBAMHBQAAAAAAAQIDBAAFBhESBwghEzEUIkFRCUKRFSMyM2FicYGSocLR/8QAHAEBAAICAwEAAAAAAAAAAAAAAAYHAQUCBAgD/8QANxEAAQMDAgQCCAMJAQAAAAAAAQACAwQFESExBhJBUWFxByIygZGhsdETksEUM1Jyc3SCorLw/9oADAMBAAIRAxEAPwDqnREoiURKIlESiJREoiURKIlESiJREoiURR68dRMVx6YuJdcms9slI0VMTJ7TS079tpUoGvjJNFF+8cB5nC5tY53sjK8lzrdgSDpGWWuR/dFkB4fqjYrWvvNsjOH1MY83t+67Ao6l2ojd8Cs1l6wYZkV2ZtluyKFJuDzhZbjBRStTgQXCgAgfNwBVr315r7wXKiqniOCdj3EZwHAnHfAOy4PppohzSMIHiCFMa2K66URKIlESiL5W4lpJUtQQkfVR0KIqV7iOqq8at7Vktkp1l+Sz8RMkwl6fbYK+DbTRBGnHl7QlQOwEL0UqKVCuuNOIZbLStgpCBPLkNJ2aBq558h99cYUhs1vbWSl8vsM38Sdh71TPT/pJdeoN0ct7cv8AZaWECRLXFcdbiwgsni0lLS21PuLKVEqUrxoq0nklCqc4W4dl4pmkq5nkQtOC9wDnvd/kHBuN9BpkD1jqJfdLi21sbEweudgCQ1o92M/+22VqNdmeIKSDKulzlPEfMtyNBX5/oXIyla/yo/5NXGzgO1MGOaT85HybgfJRA3yqJzhv5QfrlQ7tF6b2Sy59ldwZiD4+DGbbS6dAKW5JmIWvgNISoJZSkcUp0FLHsrVceEYOSSsDnFwhldGzOpDQGk67ku0JyTnA2S6yZbCQMc7Q4+Jyfdp0W19WOo8lESiJREoi1G7nHWcryu+MT2GpUayJjQo7D6AtLa1hp5xwA+xUHWkn+jQ+9ed/SJd6gXent8Ty1rWlxwcZJ5hr5AaeZVg8P0kZpJKhwySce4Y+/wAlHMNwbHJc/JvXx+1vcbihKfUhNq0PhY50Np+5J/1q4/RA0VXDHNUDnP4j/a17d1VXpAkfBeQInFvqN206nsrQwCPB6d5bYpVmiMWq2XeQbfco8ZsNtLWpOmXChIAK/ULKAr7OKHtrVl3CihhicYWBvKQdABofLxUftNdM+ZrJXlwcCNTnUa6Z8FsZUZU0VA9s7Pp5h1J/snlj/ZNn/wDtQrhpvLJcf7h//LFubictp/6Y+rlf1TVaZKIlEWGY4pqI+tH8aUKUnf3Aoi1Nx/qdn14x22TXs3uDb8qK08v0oMAJClIBIAMc+PNeW6r0oXqGokibHHhpI9l3Q4/jVnRcM0b42uLnZIHUfZQa8z590t+VTLpcHrpPeurIdlPobQtfFMdCdhtKUD5Up9kjxrfnZqFXS7T3u5x11SAHOZ0yBoHDTJJ+e63NNSx0VM6CPOAeu/RSGzX2Fi95vbdze+CYmPNy2pLyFJY/lIbKS5rikj0t6JB8ivSXoe4htlNZH0FVUMZIJHHlc4NJBA1GcZ67KmfSBaK2ouDKqCFz2coGQM6gnsvQm59jr8i0piX23S5Sbtb3G2Y0lDq1qTLaUAEpJPnVXnWXi2SwuibUsLnbAPaST0AGdVXVvt1dHUskdA8AHUlpAA+C2rkZXZId6FnfvEBi7mOZYgOSkJf9EK4lz0yeXDfjlrW/FRLIzhWLjqqg7bE7yXqov7ZLMa/SXJV/3qL2NnJLXeMzj/oxbKtOWwfyD6uV6VKVrEoiURY5CPUjup9+SSP+KItLMUj3SHi9njP4xlLT7MNltxCscn7SoIAI/k/evGNbwVxBJVSvbSOILiRq3v5q4Ybzb2xtaZRnA7/ZQvKMij2KXkVsucS52uXKlxJ7Lc+1yY/Ng+i3yHNsfmYd/SuE3D9yoHU5qouQ8rxgkZ3cds7esPevrHWQVIk/APMMjYHw8PAqcW/KrTd2S7AntTmwopKoxLmiPcfLvzWgj4cvMzQ+OkkIPUMcR8cYXdfcKSM8r5Wg9iQss7G75nsRVqx+Fc25q/36JwivMtMKa/epPqlISFKUhKEgHe1g+wJFg8GcJXVt4iqKqB0bI8uy4Y1xpjPXJB8gVoLxdaU0j44nhznaYB+PyVNDtN6f5DFbnCReH0ywJHrOywtbhUN8lFaCSo72SfOyd1pp+Nr5DO9k/LztJByDoQdRv3WwjtVI6MGMnlOCNvt2W2vZzgicHwjIEMTZ1wgSLuv4WRcHEuOuJQ2hLh5hI5ae9ZOzs7SfJr0fwbNV1lqFbWtDXzEu0yMjQA4JO4GfLBVbXhkUVUYYTlrBj9T9Vf1TlaRKIlEVFd5vW+59Buikm9WPgi+3CW3a4EhxAWmO4tK1qdKT4JShpwgHY5cdgjYJFx9uPX/I8hzR6FPzDIZt5Ki6p6RPdWkq1y4+VEaA/Lrjrxr6VxewSNLTsexI+Y1HuWWu5HAjp7/qtquk9iuPVzCol9ew2VeZTZVEelx7O5IQpTaj/CoII8ghXEHwVEVQd64d4gNY9tK58kQ9kmToemrs6beKte23i0CmaZ2tY/qA3r30HXdVf3B5Hc+nl5VjcWFKxFiPGTNlpTFXCecKuWtDSVBICd7HvvW/HmZ8I2a4UjHTXN7+YHDWF5IA74BIOSf16qN8QXGkqHCOia3GMlwaAc9skZXj9t3eplvT7Iot5h5Fd7njjEhKLnZrnIW806zva+CVKUEL47KVp0dgb2Ng2YoVldfrj0Vwy6XF6c9Zg28+suOpjSXmGnFk7UpTba0oJJ2SSNnfndaSoslrqpv2iopWPf3LGk/Ehd6OtqomfhxyuA7AlS63W6JZ4EeDBjNQ4UdtLTMdhAQ22gDQSlI8AAfQVuQ0NAa0YC6ZJJyV+msrCURKIq47gOilt6/9MbjiNxkKgLdUiRDnoRzVFkIO0OcdjkPJSpOxtKlAEE7BFztj/hcdT1ZeebmLMsk8FXsSnFbb+4R6QWVa/KdD6cteaLC6Q9FOk1r6IdM7LhtpcXIj29tRclOgBch5aitx1QHtyUokD6DQ9hRZVD96fZjK7hZdvyfFpsKFlcOMIL8e5FSI82OFKUkFaUqKFpK16PEhQVo60CCKgO3/APDIyW35lBl523aLNi8KQmS9bbe/6z09SSCGzxSEobVoBStlRGwAN8gWF0vospREoiURKIlESiJREoiURKIlESiJREoiURKIlESiJREoiURKIlEX/9k=" } ] } } }}
An update from the dealer system to the CRS Services indicating someone is working on this. This moves the request from the submitted status to the received status. The text of the update is not used. The update createdBy value should either be a Cat CWS username, or a username preceded by “local:” to indicate it is a username in the local dealer system. The localId and remoteId on the request are flipped (localId is the sending system’s id, remoteId is the id on the receiving system if known) and populated appropriately.
{ dealerCode: "A000", customerNumber: "001234", submittedMessageId: "rmsmessage1", submittedTime: "2022-01-01T00:02:00Z", messageType: "request", payload: { request: { localId: "srv1", remoteId: "1234567", requestType: "service", status: "received" }, requestUpdate: { status: "received", createdDate: "2022-01-01T00:01:30Z", createdBy: "local:rentalCoordinator", title: null, text: null, properties: { userName: "Jennifer Rents" } } }}
An update from the dealer system to the CRS Services indicating the request has been scheduled. This moves the request from the received status to the scheduled status. The text of the update is only used if the dealer user wishes to add a specific note to the customer as part of this update. The update createdBy value should either be a Cat CWS username, or a username preceded by “local:” to indicate it is a username in the local dealer system. While not explicitly enforced in the API, the date the service is scheduled should be included as a property of the update (updateDate), as this indicates to the customer when service has been scheduled to be performed.
{ dealerCode: "A000", customerNumber: "001234", submittedMessageId: "rmsmessage2", submittedTime: "2022-01-01T00:02:00Z", messageType: "request", payload: { request: { localId: "srv1", remoteId: "1234567", requestType: "service", status: "scheduled" }, requestUpdate: { status: "scheduled", createdDate: "2022-01-01T00:01:45Z", createdBy: "local:rentalCoordinator", title: null, text: null, updateDate: "2022-01-03T16:00:00Z" properties: { userName: "Jennifer Rents", } } }}
Finally, once the service has been completed, an update from the dealer system to the CRS Services indicating the request has been closed as requested.
{ dealerCode: "A000", customerNumber: "001234", submittedMessageId: "rmsmessage3", submittedTime: "2022-01-03T16:40:00Z", messageType: "request", payload: { request: { localId: "srv1", remoteId: "1234567", requestType: "service", status: "closed" }, requestUpdate: { status: "closed", createdDate: "2022-01-01T00:01:45Z", createdBy: "local:rentalCoordinator", title: null, text: null, properties: { userName: "Jennifer Rents" } } }}
A sample update message, from the CRS Services to the dealer system indicating the customer user would like to cancel the request. This moves the request to the ‘canceled’ status, regardless of where it was previously, unless it was closed. Closed requests cannot be updated any further.
{ dealerCode: "A000", customerNumber: "001234", submittedMessageId: "message3", submittedTime: "2022-01-01T00:01:30Z", messageType: "request", payload: { request: { localId: "1234567", remoteId: "srv1", requestType: "service", status: "canceled" }, requestUpdate: { status: "canceled", createdDate: "2022-01-01T00:01:30Z", createdBy: "john.customer@customerxyz.com", title: "John Customer has asked to cancel the transfer request (1234567)", text: "It just started. Sorry. Back to digging.", properties: { userName: "John Customer" } } }}
An update from the dealer system to the CRS Services indicating the request has been canceled as requested.
{ dealerCode: "A000", customerNumber: "001234", submittedMessageId: "rmsmessage3", submittedTime: "2022-01-01T00:02:00Z", messageType: "request", payload: { request: { localId: "srv1", remoteId: "1234567", requestType: "service", status: "closed" }, requestUpdate: { status: "closed", createdDate: "2022-01-01T00:01:45Z", createdBy: "local:rentalCoordinator", title: "Canceled", text: null, properties: { userName: "Jennifer Rents" } } }}
Rental Request Integration
The JSON required to integrate Lead updates with the CRS Web Services is:
{ dealerCode: <code>, customerNumber: <dcn>, submittedMessageId: <submittedMessageId>, submittedTime: <date-time>, // ISO8601 timestamp from submitting server messageType: "request", payload: { request: {<request details>}, requestUpdate: {<request update details>} }}
This will include the request details necessary to initiate a request for a message that includes the start of a request, and it will include an update to an existing request (more information from the customer user, an update to cancel the request, etc.) for any message that is intended to indicate progress on a request. Rental requests follow this path.
Brown and green text are notifications sent to customer users (brown) or dealer users (green) based on activity on the request. When a request is part of the integration flow, it is assumed that the integrated system on the dealer side will handle dealer-direction notifications, but it is also expected that the dealer-side of the integration will have process points that trigger the notifications that are to be sent to customer users.
Each point where a notification is sent back to the customer user is important to the business logic of the request and is encapsulated in a request update sent back to the CRS Web Services. Any time a customer has an interaction with the request, that interaction will be sent to the dealer system via a message that should be presented with the original request and should generate a notification within the dealer system in whatever way the dealer system notifies users natively which is routed to the appropriate user to handle the update. Several additional properties are included in the payload of a rental request to indicate the equipment required for the rental, options like delivery, whether a quote is required or the rental is already approved, a new jobsite if the rental is not on an existing jobsite or the existing jobsite name. The structure of an initial rental request message payload is as follows:
request: { localId: <alphanumericId>, // the request id in the sending system. remoteId: <alphanumericId>, // For initial submission this will always be null or missing. // For updates remoteId should be populated if known. requestType: "quote", status: "submitted", createdDate: <date>, createdBy: <userSpec>, title: "Rental Request", text: "Text of the rental request", // Description of rental request requestedDate: "2023-01-01T00:00:00Z", properties: { "catalogItems":[ <array of catalog items if this was submission of a populated shopping cart> ], "language":"<lead locale>", "jobsite-city":"<lead city>", "rental-start":"01/22/2023", "latitude":"", "longitude":"", "name-last":"<lead last name>", "delivery":"true|false", "comments":"", // Contents of the lead, duplicated from text above "specialInformation":"", // And special instructions associated with this rental (e.g. must be on site by 8am) "rental-end":"01/23/2023", "name-first":"<lead first name>", "jobsite-address-2":"", "new-jobsite":"true|false", "quoteRequired":"true|false", "jobsite-zip-postal":"<lead zip>", "jobsite-country":"<lead country>", "jobsite-address-1":"<lead address>", "jobsite-name":"<jobsite name if available>", "poNumber":"" }},requestUpdates: []
catalogItems is an array of objects with a lot of catalog data attached to them, but the relevant elements of the items are in the structure below:
{ "image":{ "imageUrl":"https://www.catrentalstore.com/content/dam/crs/products/aerial-equipment/scissor-lifts/C10345475.jpg", }, "quantity":1, "estimatedRate":{ "daily":{ "amount":65, "currency":"USD" }, "weekly":{ "amount":190, "currency":"USD" }, "monthly":{ "amount":465, "currency":"USD" } }, "attachments":"Attachments: <br/>List name 1<br/> Item name 1 ($198)<br/>LN 2<br/> IN1 ($198)<br/>LN3<br/> IN3-1 ($198)<br/><br/>Auto Leads Smoke Testing", "path":"/aerial-equipment/scissor-lifts", "name":"BREAKER, 60LB HYDRAULIC PAVING-Test", "properties":{ }, "categoryGroup":{ "rmsId":"PB 60H", "title":"BREAKER, 60LB HYDRAULIC PAVING", } }
In that structure, the image.imageUrl can be used to get an image of the catalog item, the quantity is the number of the item requested, the estimatedRate is the estimated cost of renting the asset, the attachments is a text description of the attachments requested, the name is the name of the item in the catalog, the categoryGroup.rmsId is the catalog ID of the item in the dealer’s catalog (in their RMS), and categoryGroup.title is the name of the item in the dealer’s catalog (in their RMS).
If the message is an update and not a request initialization, the request message payload can be simplified for bandwidth, and an update is included:
request: { localId: <alphanumericId>, // the request id in the sending system. remoteId: <alphanumericId>, // For updates remoteId should be populated if known. requestType: "quote", status: "submitted|received|quoted|approved|canceled|closed" // status after update},requestUpdate: { status: "submitted|received|quoted|approved|canceled|closed", createdDate: <date>, // timestamp for this request update createdBy: <userSpec>, // user who initiated this request update titleToken: <translation token for translation to dealer locale if desired>, titleContent: {}, // a content map of key-value pairs for swapping content into the translated title title: <message title>, // often null, this is based on the status of the request/update text: <message text if any>, // null for many updates, but could have a note attached updateDate: null, properties: { userName: <createdBy user full name>, attachments: [{ // included for attaching files, specifically quotes, to the request filename: <filename>, mimetype: <mimetype>, contents: <base64-encoded file contents> }] }}
When a rental request is closed, it is suggested that the request be closed with an appropriate disposition. The list of dispositions is as follows:
- Won
- No Deal - Credit
- No Deal - Don’t carry requested equipment
- No Deal - No Response
- Lost - Availability
- Lost - Competitor
- Lost - Customer Declined
To illustrate both potential interactions and the structure of the message content, a potential path through the process is illustrated here with integration messages.
An initial request, initiated on the CRS portal:
{ dealerCode: "A000", customerNumber: "001234", submittedMessageId: "message1", submittedTime: "2022-01-01T00:00:30Z", messageType: "request", payload: { request: { localId: 1234567, remoteId: null, requestType: "quote", status: "submitted", createdDate: "2022-01-01T00:00:30Z", createdBy: null, title: "Rental Request", text: "10x 10000 gallon water trucks", requestedDate: "2023-01-01T00:00:00Z", properties: { "catalogItems":[], "language":"en_US", "jobsite-city":"Mason", "rental-start":"01/22/2023", "latitude":"", "longitude":"", "name-last":"Customer", "delivery":"false", "comments":"10x 10000 gallon water trucks ", "specialInformation":"", "rental-end":"01/23/2023", "name-first":"John", "jobsite-address-2":"", "new-jobsite":"", "quoteRequired":"false", "jobsite-zip-postal":"45040", "jobsite-country":"us", "jobsite-address-1":"Mason", "jobsite-name":"Mason", "poNumber":"" } } }}
An update message, in this case from the customer to give more information. The request has been stripped of information that is not necessary in an update. That is optional; but the additional information should already be available from the previous message.
{ dealerCode: "A000", customerNumber: "001234", submittedMessageId: "message2", submittedTime: "2022-01-01T00:01:30Z", messageType: "request", payload: { request: { localId: "1234567", remoteId: null, requestType: "quote", status: "submitted" }, requestUpdate: { status: "submitted", createdDate: "2022-01-01T00:01:30Z", createdBy: "john.customer@customerxyz.com", title: "John Customer has sent more info about a rental request (1234567)", text: "All of those water trucks should come filled with water if possible.", properties: { userName: "John Customer" } } }}
An update from the dealer system to the CRS Services indicating someone is working on this. This moves the request from the submitted status to the received status. The text of the update is not used. The update createdBy value should either be a Cat CWS username, or a username preceded by “local:” to indicate it is a username in the local dealer system. The localId and remoteId on the request are flipped (localId is the sending system’s id, remoteId is the id on the receiving system if known) and populated appropriately.
{ dealerCode: "A000", customerNumber: "001234", submittedMessageId: "message2", submittedTime: "2022-01-01T00:01:30Z", messageType: "request", payload: { request: { localId: "1234567", remoteId: null, requestType: "quote", status: "submitted" }, requestUpdate: { status: "submitted", createdDate: "2022-01-01T00:01:30Z", createdBy: "john.customer@customerxyz.com", title: "John Customer has sent more info about a rental request (1234567)", text: "All of those water trucks should come filled with water if possible.", properties: { userName: "John Customer" } } }}
An update from the dealer system to the CRS Services indicating the request has been scheduled. This moves the request from the received status to the closed status, and is only valid if the request has “quoteRequired” set to false. The text of the update is only used if the dealer user wishes to add a specific note to the customer as part of this update. The update createdBy value should either be a Cat CWS username, or a username preceded by “local:” to indicate it is a username in the local dealer system.
{ dealerCode: "A000", customerNumber: "001234", submittedMessageId: "rmsmessage2", submittedTime: "2022-01-01T00:02:00Z", messageType: "request", payload: { request: { localId: "srv1", remoteId: "1234567", requestType: "quote", status: "scheduled" }, requestUpdate: { status: "closed", createdDate: "2022-01-01T00:01:45Z", createdBy: "local:rentalCoordinator", title: null, text: "We will drop these off in the morning, thank you.", updateDate: "2022-01-03T16:00:00Z" properties: { userName: "Jennifer Rents", disposition: "Won" } } }}
A sample update message, from the CRS Services to the dealer system indicating the customer user would like to cancel the request. This moves the request to the ‘canceled’ status, regardless of where it was previously, unless it was closed. Closed requests cannot be updated any further.
{ dealerCode: "A000", customerNumber: "001234", submittedMessageId: "message3", submittedTime: "2022-01-01T00:01:30Z", messageType: "request", payload: { request: { localId: "1234567", remoteId: "srv1", requestType: "quote", status: "canceled" }, requestUpdate: { status: "canceled", createdDate: "2022-01-01T00:01:30Z", createdBy: "john.customer@customerxyz.com", title: "John Customer has asked to cancel the rental request (1234567)", text: "We don't need water anymore.", properties: { userName: "John Customer" } } }}
An update from the dealer system to the CRS Services indicating the request has been canceled as requested.
{ dealerCode: "A000", customerNumber: "001234", submittedMessageId: "rmsmessage3", submittedTime: "2022-01-01T00:02:00Z", messageType: "request", payload: { request: { localId: "srv1", remoteId: "1234567", requestType: "quote", status: "closed" }, requestUpdate: { status: "closed", createdDate: "2022-01-01T00:01:45Z", createdBy: "local:rentalCoordinator", title: "Canceled", text: null, properties: { userName: "Jennifer Rents", disposition: "Lost - Customer Declined" } } }}
Lead Request Integration
The JSON required to integrate Lead updates with the CRS Web Services is:
{ dealerCode: <code>, customerNumber: <dcn>, submittedMessageId: <submittedMessageId>, submittedTime: <date-time>, // ISO8601 timestamp from submitting server messageType: "request", payload: { request: {<request details>}, requestUpdate: {<request update details>} }}
This will include the request details necessary to initiate a request for a message that includes the start of a request, and it will include an update to an existing request (update information on the request, reject the request as wrong territory, or close the request with an appropriate disposition indicating the result of the lead) for any message that is intended to indicate progress on a request. Lead requests follow this path.
When a request is part of the integration flow, it is assumed that the integrated system on the dealer side will handle dealer-direction notifications, but it is also expected that the dealer-side of the integration will update the CRS Services via the integration messaging API to indicate lead status.
Lead requests are unique in that they do not include a conversation with the submitting user; they are entirely handled by the dealer(s) and CRS personnel involved in handling the request, so there is less interaction involved in implementing Lead request integration. However, because lead requests are screened when submitted and can be transferred between dealers if they are incorrectly routed, they will always arrive at the dealer with some number of updates already attached. Those updates indicate things like how long the lead was held for screening, whether the lead had already been routed to a dealer, and potentially reasons for the dealer rejecting it or reasons for it being assigned to your dealer.
Several additional properties are included in the payload of a lead request; these are all indicated below. Some may only be relevant to some dealers; the implementation and dissemination of lead information within a dealership is left up to the dealer implementation. The structure of an initial Lead request message payload is as follows:
requestType: "lead", status: "submitted", createdDate: <date>, createdBy: <userSpec>, title: "Lead Request", text: "Text of the lead request", // May be blank if lead includes shopping cart contents requestedDate: "2023-01-01T00:00:00Z", properties: { "zift-partner-id":"", "name-company":"<lead company name>", "elqFormName":"cat-rental-store-initiate-dealer", "utm_medium":"<utm value>", "latitude":"", "catalogItems":[ <array of catalog items if this was submission of a populated shopping cart> ], "GACLIENTID":"<GACLIENTID if known>", "GAUSERID":"< GAUSERID / SFCID if known>", "SFCID":"< GAUSERID / SFCID if known>", "language":"<lead locale>", "phone-business":"<lead phone>", "subscription":"<lead opt-in marketing choice>", "elqSiteID":"2936", "elqPost":"", "formURL":"", "elqCustomerGUID":"", "jobsite-city":"<lead city>", "rental-start":"01/22/2023", "zift-id":"", "email":"<lead email>", "utm_content":"<utm value>", "longitude":"", "name-last":"<lead last name>", "delivery":"false", "dealer-code":"<lead dealer code>", "comments":"", // Contents of the lead, especially if this does not include catalogItems:[] "rental-end":"01/23/2023", "utm_campaign":"<utm value>", "name-first":"<lead first name>", "jobsite-address-2":"", "new-jobsite":"", "utm_term":"", "jobsite-zip-postal":"<lead zip>", "jobsite-country":"<lead country>", "dealer-name":"<lead initial dealer name>", "jobsite-address-1":"<lead address>", "nationalAccountCode":"", "jobsite-name":"", "poNumber":"", "referring-url":"/ohiocat/en_US/request.html", "utm_source":"<utm value>", "GATRACKID":"", "googleGeocode":{ "lat":40.143105, "lng":47.576927 } }},requestUpdates: [ { status: "lead_screening", createdDate: "2022-01-01T00:01:30Z", createdBy: "crs-server", titleToken: "svc-request-lead-hold-for-screen", titleContent: {}, title: "Lead Held for Screening", text: "", properties: { userName: "" } }, { status: "submitted", createdDate: "2022-01-01T00:10:30Z", createdBy: "crs-server", titleToken: "svc-request-lead-completed-screening", titleContent: {}, title: "Lead Completed Screening", text: "", properties: { userName: "" } }]
catalogItems is an array of objects with a lot of catalog data attached to them, but the relevant elements of the items are in the structure below:
{ "image":{ "imageUrl":"https://www.catrentalstore.com/content/dam/crs/products/aerial-equipment/scissor-lifts/C10345475.jpg", }, "quantity":1, "estimatedRate":{ "daily":{ "amount":65, "currency":"USD" }, "weekly":{ "amount":190, "currency":"USD" }, "monthly":{ "amount":465, "currency":"USD" } }, "attachments":"Attachments: <br/>List name 1<br/> Item name 1 ($198)<br/>LN 2<br/> IN1 ($198)<br/>LN3<br/> IN3-1 ($198)<br/><br/>Auto Leads Smoke Testing", "path":"/aerial-equipment/scissor-lifts", "name":"BREAKER, 60LB HYDRAULIC PAVING-Test", "properties":{ }, "categoryGroup":{ "rmsId":"PB 60H", "title":"BREAKER, 60LB HYDRAULIC PAVING", } }
In that structure, the image.imageUrl can be used to get an image of the catalog item, the quantity is the number of the item requested, the attachments is a text description of the attachments requested, the path is the page the user was on when they added this to their shopping cart, the name is the name of the item in the catalog, the categoryGroup.rmsId is the catalog ID of the item in the dealer’s catalog (in their RMS), and categoryGroup.title is the name of the item in the dealer’s catalog (in their RMS).
If the message is an update and not a request initialization, the request message payload can be simplified for bandwidth, and an update is included:
request: { localId: <alphanumericId>, // the request id in the sending system. remoteId: <alphanumericId>, // For updates remoteId should be populated if known. requestType: "lead", status: "submitted|closed" // request status after this update},requestUpdate: { status: "submitted|closed", createdDate: <date>, // timestamp for this request update createdBy: <userSpec>, // user who initiated this request update title: <message title>, // often null, this is based on the status of the request/update text: <message text if any>, // null for many updates, but could have a note attached updateDate: null, properties: { userName: <createdBy user full name>, disposition: <updated disposition of the lead if known> }}
Lead requests can be transferred from dealer to dealer, and the history of the request is preserved as a history of request updates that is transferred with the request to the dealer. This history includes how long the request spent in lead screening (to screen the lead for ineligible customers based on Caterpillar criteria), whether and which other dealers the lead may have been directed to previously, and comments from dealers and CRS personnel related to transferring the lead to a dealer. Because all leads are passed through the lead screening process, all lead requests will have at least one request update attached to them to indicate the result of lead screening. There will be more updates if the lead was held for manual screening, was not automatically sent to a dealer, or has been rejected by a dealer earlier as “Wrong Territory”.
When a lead is closed, it should be closed with an appropriate disposition. The list of dispositions is as follows:
- Won
- No Deal - Credit
- No Deal - Don’t carry requested equipment
- No Deal - No Response
- Lost - Availability
- Lost - Competitor
- Lost - Customer Declined
- Not A Real Lead
In addition, if the lead has been routed to the wrong dealer (jobsite is in another dealer’s territory), it must be updated with a status of ‘submitted’ and a disposition of ‘Wrong Territory’. This will cause the CRS system to route the lead to CRS personnel for reassignment to a dealer, and will end request handling for this request in the local system.
To illustrate both potential interactions and the structure of the message content, a potential path through the process is illustrated here with integration messages.
An initial request, initiated on the CRS portal and passed automatically through lead screening:
{ dealerCode: "A000", customerNumber: null, submittedMessageId: "message1", submittedTime: "2022-01-01T00:00:30Z", messageType: "request", payload: { request: { localId: 1234567, remoteId: null, requestType: "lead", status: "submitted", createdDate: "2022-01-01T00:00:30Z", createdBy: null, title: "Lead Request", text: "10x 10000 gallon water trucks", requestedDate: "2023-01-01T00:00:00Z", properties: { "zift-partner-id":"", "name-company":"ACME Water Supply", "elqFormName":"cat-rental-store-initiate-dealer", "utm_medium":"<utm value>", "latitude":"", "catalogItems":[], "GACLIENTID":"<GACLIENTID if known>", "GAUSERID":"< GAUSERID / SFCID if known>", "SFCID":"< GAUSERID / SFCID if known>", "language":"en_US", "phone-business":"513-555-5555", "subscription":"false", "elqSiteID":"2936", "elqPost":"", "formURL":"", "elqCustomerGUID":"", "jobsite-city":"Mason", "rental-start":"01/22/2023", "zift-id":"", "email":"john@acme.com", "utm_content":"<utm value>", "longitude":"", "name-last":"Customer", "delivery":"false", "dealer-code":"<lead dealer code>", "comments":"10x 10000 gallon water trucks ", "rental-end":"01/23/2023", "utm_campaign":"<utm value>", "name-first":"John", "jobsite-address-2":"", "new-jobsite":"", "utm_term":"", "jobsite-zip-postal":"45040", "jobsite-country":"us", "dealer-name":"Ohio Cat", "jobsite-address-1":"Mason", "nationalAccountCode":"", "jobsite-name":"Mason", "poNumber":"", "referring-url":"/ohiocat/en_US/request.html", "utm_source":"<utm value>", "GATRACKID":"", "googleGeocode":{ "lat":40.143105, "lng":47.576927 } } }, requestUpdates: [ { status: "submitted", createdDate: "2022-01-01T00:01:30Z", createdBy: "crs-server", title: "Lead Completed Screening", text: "", properties: { userName: "" } } ] }}
An update that routes the request back to CRS personnel because it was incorrectly routed to this dealer:
{ dealerCode: "A000", customerNumber: null, submittedMessageId: "rmsmessage3", submittedTime: "2022-01-03T16:40:00Z", messageType: "request", payload: { request: { localId: "lead1", remoteId: "1234567", requestType: "lead", status: "submitted" }, requestUpdate: { status: "submitted", createdDate: "2022-01-01T00:01:45Z", createdBy: "local:rentalCoordinator", title: null, text: null, properties: { userName: "Jennifer Rents", disposition: "Wrong Territory" } } }}
An update that closes the lead request and notifies CRS of the disposition:
{ dealerCode: "A000", customerNumber: null, submittedMessageId: "rmsmessage3", submittedTime: "2022-01-03T16:40:00Z", messageType: "request", payload: { request: { localId: "lead1", remoteId: "1234567", requestType: "lead", status: "closed" }, requestUpdate: { status: "closed", createdDate: "2022-01-01T00:01:45Z", createdBy: "local:rentalCoordinator", title: null, text: null, properties: { userName: "Jennifer Rents", disposition: "Lost - Availability" } } }}
Unlike other requests, the disposition of a lead request can be changed after it is closed if the customer changes their mind, or the situation changes. An update that notifies CRS of an updated disposition:
{ dealerCode: "A000", customerNumber: null, submittedMessageId: "rmsmessage3", submittedTime: "2022-01-03T16:40:00Z", messageType: "request", payload: { request: { localId: "lead1", remoteId: "1234567", requestType: "lead", status: "closed" }, requestUpdate: { status: "closed", createdDate: "2022-01-01T00:01:45Z", createdBy: "local:rentalCoordinator", title: null, text: null, properties: { userName: "Jennifer Rents", disposition: "Lost - Availability" } } }}
Asset-centric Messaging Integration
The JSON required to integrate asset-based messaging with the CRS Web Services is:
{ dealerCode: <code>, customerNumber: <dcn>, submittedMessageId: <submittedMessageId>, submittedTime: <date-time>, // ISO8601 timestamp from submitting server messageType: "message", payload: { message: {<message chain details>} }}
This will include the message chain details necessary to initiate or continue a message chain for communication centered on a specific asset on a specific contract with a specific customer outside of a request. It will include information to link it to the asset, contract, and customer as well as information that indicates whether the message chain is still active, and one or more messages in the chain. Messages from the CRS Services will include up to ten messages in the chain so that the chain can be updated as necessary locally by the dealer system. Messages from the dealer system to CRS can include up to ten messages, or only a new message being added to the chain, at the developer’s discretion. Messages in a chain within a single message should be checked for local existence, and any missing messages locally should be added. Timestamps on individual messages could vary by small amounts locally and in the response from CRS, as the timestamp applied to a message is the time it was added to the message chain in CRS, not the time submitted locally to the dealer’s system. It is suggested that timestamps be updated locally when adjustments come via a CRS message, as that will reconcile message ordering differences across the systems.
A CRS message that includes the payload attribute message.messageChain.active=false indicates that the message chain has been deactivated on the CRS. This happens when the associated asset is no longer on rent with the given customer on the given contract. This should deactivate the messageChain locally to the dealer as well.
The CRS organizes asset-based messaging in line with request activity on the same asset so that all communication can be viewed in context of activities around the asset. This pattern is suggested to the dealer developer as well.
The structure of the message payload is as follows:
message: { messageChain: { localId: <alphanumericId>, // the request id in the sending system. remoteId: <alphanumericId>, // For initial submission this will always be null or missing. chainType: "asset", createdDate: <date>, createdBy: <userSpec>, active: <boolean>, properties: { userName: <createdBy user full name> } }, messages: [ // this is an array that can contain 1-10 message objects in reverse chronological order. { createdDate: <date>, createdBy: <userSpec>, messageText: <text> properties: { userName: <createdBy user full name> } } ], asset: { "rentedAssetId":"34567", "equipmentAssetId":"23456", "serialNumber":"12345" }, contract: { contractId: <contractId> }}
Layout Types
Message Data
The message JSON object array is submitted with no query string arguments. Messages are submitted one at a time, in a FIFO queued order so that they are handled in order.
Sample endpoint (authentication as specified above, dealer parameter optional if endpoint is dealer-specific):
POST: https://rental-api.your-dealer-system.com/api/v1/message
Returns a success or failure message based on the error handling above.
Parameters: none
Return Type
Response types:
200
response with the content of the message repeated back (with any additional values, like enqueued time, id, etc.) will indicate the message has been queued locally for handling.
402
(bad request) error indicates there is a problem with the message body that causes it to be invalid.
403
error is a permission error, can be retried.
404
is a server failure to route the request, and it should be retried, similar to a server error.
5xx is a server error, it should be retried after an appropriate pause.
Submission Body (JSON)
This is a complete list of fields in the message structure.
Required | Field | Type | Size/Type Limits | Description | Default | Sample |
---|---|---|---|---|---|---|
false | enqueuedTime |
Datetime | Null in submission, present in submission response, the time the message entered the queue | |||
false | enqueuedClientId |
String | Null in submission | |||
false | attemptTime |
Datetime | Null – used internally | |||
false | attemptCount |
Integer | Null – used internally | |||
false | deliveredTime |
Datetime | Null – used internally | |||
false | active |
Boolean | Null – used internally | |||
true | dealerCode |
String | Dealer code | |||
false | customerNumber |
String | Customer DCN – is required for most request or message types, but is always required for contract and invoice types. | |||
true | submittedPriority |
Integer | Higher priority skips queue | 1 | ||
true | submittedMessageId |
String | Message ID in submitting system | |||
true | submittedTime |
Datetime | ISO8601 time on submitting server | |||
true | messageType |
String | Type of message | One of the following: request contract invoice message catalog document |
||
false | payload |
Object | Payload for the message. Can be missing for contract, invoice, catalog, or document message types, but will include more information for more complicated types. | |||
false | payload.errorCode |
String | If this message is about an error, this will be the code. | |||
false | payload.errorSubmittedMessageId |
String | If this message is about an error, this will be the submittedMessageId of the erroring message. | |||
false | payload.request |
Object | Object containing the request details. | |||
false | payload.request.localId |
String | Local ID of the request (local to the sender) | |||
false | payload.request.remoteId |
String | Remote ID of the request (local to the receiver) | |||
false | payload.request.requestType |
String | Type of request | |||
false | payload.request.status |
String | Status of the request after processing this message. | |||
false | payload.request.createdDate |
Datetime | Creation date of the request | |||
false | payload.request.createdBy |
String | userId of the request creator. If the userId is not local to the sender, it will be preceded by “remote:” | winkeda remote:george@gmail.com |
||
false | payload.request.title |
String | Title of the request | |||
false | payload.request.text |
String | Text of the request | |||
false | payload.request.requestedDate |
Datetime | Requested date (if appropriate) | |||
false | payload.request.properties |
Object | Object containing additional properties pertaining to the request. Request properties are relevant to specific request types, and should be verified with the request types. |
|||
false | payload.request.properties.currentPoNumber |
String | ||||
false | payload.request.properties.poNumber |
String | ||||
false | payload.request.properties.userName |
String | ||||
false | payload.request.properties.jobsiteId |
String | ||||
false | payload.request.properties.name |
String | ||||
false | payload.request.properties.firstName |
String | ||||
false | payload.request.properties.lastName |
String | ||||
false | payload.request.properties.address1 |
String | ||||
false | payload.request.properties.address2 |
String | ||||
false | payload.request.properties.city |
String | ||||
false | payload.request.properties.state |
String | ||||
false | payload.request.properties.postCode |
String | ||||
false | payload.request.properties.country |
String | ||||
false | payload.request.properties.latitude |
String | ||||
false | payload.request.properties.longitude |
String | ||||
false | payload.request.properties.phoneNumber |
String | ||||
false | payload.request.properties.transportationNeeded |
Boolean | ||||
False | payload.request.properties.isWorking |
Boolean | ||||
false | payload.request.properties.images |
Array | ||||
false | payload.request.properties.images[#] |
Object | ||||
false | payload.request.properties.images[#].filename |
String | ||||
false | payload.request.properties.images[#].mimetype |
String | ||||
false | payload.request.properties.images[#].contents |
String | ||||
false | payload.request.properties.language |
String | ||||
false | payload.request.properties.name-first |
String | ||||
false | payload.request.properties.name-last |
String | ||||
false | payload.request.properties.quoteRequired |
Boolean | ||||
false | payload.request.properties.delivery |
Boolean | ||||
false | payload.request.properties.rental-end |
String | ||||
false | payload.request.properties.rental-start |
String | ||||
false | payload.request.properties.new-jobsite |
Boolean | ||||
false | payload.request.properties.jobsite-name |
String | ||||
false | payload.request.properties.jobsite-zip-postal |
String | ||||
false | payload.request.properties.jobsite-country |
String | ||||
false | payload.request.properties.jobsite-address-1 |
String | ||||
false | payload.request.properties.jobsite-address-2 |
String | ||||
false | payload.request.properties.jobsite-city |
String | ||||
false | payload.request.properties.comments |
String | ||||
false | payload.request.properties.specialInformation |
String | ||||
false | payload.request.properties.zift-partner-id |
String | ||||
false | payload.request.properties.zift-id |
String | ||||
false | payload.request.properties.elqSiteID |
String | ||||
false | payload.request.properties.elqPost |
String | ||||
false | payload.request.properties.elqFormName |
String | ||||
false | payload.request.properties.elqCustomerGUID |
String | ||||
false | payload.request.properties.utm_medium |
String | ||||
false | payload.request.properties.utm_content |
String | ||||
false | payload.request.properties.utm_campaign |
String | ||||
false | payload.request.properties.utm_term |
String | ||||
false | payload.request.properties.utm_source |
String | ||||
false | payload.request.properties.GACLIENTID |
String | ||||
false | payload.request.properties.GAUSERID |
String | ||||
false | payload.request.properties.GATRACKID |
String | ||||
false | payload.request.properties.SFCID |
String | ||||
false | payload.request.properties.formURL |
String | ||||
false | payload.request.properties.referring-url |
String | ||||
false | payload.request.properties.dealer-code |
String | ||||
false | payload.request.properties.dealer-name |
String | ||||
false | payload.request.properties.name-company |
String | ||||
false | payload.request.properties.phone-business |
String | ||||
false | payload.request.properties.subscription |
String | ||||
false | payload.request.properties.email |
String | ||||
false | payload.request.properties.nationalAccountCode |
String | ||||
false | payload.request.properties.googleGeocode |
Object | ||||
false | payload.request.properties.googleGeocode.lat |
String | ||||
false | payload.request.properties.googleGeocode.lng |
String | ||||
false | payload.request.properties.catalogItems |
Array | ||||
false | payload.request.properties.catalogItems[#] |
Object | ||||
false | payload.request.properties.catalogItems[#].image |
Object | ||||
false | payload.request.properties.catalogItems[#].image.imageUrl |
String | ||||
false | payload.request.properties.catalogItems[#].quantity |
Integer | ||||
false | payload.request.properties.catalogItems[#].estimatedRate |
Object | ||||
false | payload.request.properties.catalogItems[#].estimatedRate.daily |
Object | ||||
false | payload.request.properties.catalogItems[#].estimatedRate.daily.amount |
Double | ||||
false | payload.request.properties.catalogItems[#].estimatedRate.daily.currency |
String | ||||
false | payload.request.properties.catalogItems[#].estimatedRate.weekly |
Object | ||||
false | payload.request.properties.catalogItems[#].estimatedRate.weekly.amount |
Double | ||||
false | payload.request.properties.catalogItems[#].estimatedRate.weekly.currency |
String | ||||
false | payload.request.properties.catalogItems[#].estimatedRate.monthly |
Object | ||||
false | payload.request.properties.catalogItems[#].estimatedRate.monthly.amount |
Double | ||||
false | payload.request.properties.catalogItems[#].estimatedRate.monthly.currency |
String | ||||
false | payload.request.properties.catalogItems[#].attachments |
String | ||||
false | payload.request.properties.catalogItems[#].path |
String | ||||
false | payload.request.properties.catalogItems[#].name |
String | ||||
false | payload.request.properties.catalogItems[#].properties |
Object | ||||
false | payload.request.properties.catalogItems[#].categoryGroup |
Object | ||||
false | payload.request.properties.catalogItems[#].categoryGroup.rmsId |
String | ||||
false | payload.request.properties.catalogItems[#].categoryGroup.title |
String | ||||
false | payload.request.contract |
Object | ||||
false | payload.request.contract.contractNumber |
String | ||||
false | payload.request.contract.contractId |
String | ||||
false | payload.request.jobsite |
Object | ||||
false | payload.request.jobsite.jobsiteId |
String | ||||
false | payload.request.jobsite.name |
String | ||||
false | payload.request.jobsite.firstName |
String | ||||
false | payload.request.jobsite.lastName |
String | ||||
false | payload.request.jobsite.address1 |
String | ||||
false | payload.request.jobsite.address2 |
String | ||||
false | payload.request.jobsite.city |
String | ||||
false | payload.request.jobsite.state |
String | ||||
false | payload.request.jobsite.postCode |
String | ||||
false | payload.request.jobsite.country |
String | ||||
false | payload.request.jobsite.latitude |
String | ||||
false | payload.request.jobsite.longitude |
String | ||||
false | payload.request.jobsite.phoneNumber |
String | ||||
false | payload.request.assets |
Array | ||||
false | payload.request.assets[#] |
Object | ||||
false | payload.request.assets[#].rentedAssetId |
String | ||||
false | payload.request.assets[#].equipmentAssetId |
String | ||||
false | payload.request.assets[#].serialNumber |
String | ||||
false | payload.requestUpdate |
Object | requestUpdate object for passing a single update to a request. The request is specified with an abbreviated request object. |
|||
false | payload.requestUpdate.status |
String | ||||
false | payload.requestUpdate.createdDate |
Datetime | ||||
false | payload.requestUpdate.createdBy |
String | ||||
false | payload.requestUpdate.titleToken |
String | ||||
false | payload.requestUpdate.titleContent |
Object | Content map of tokens to values. This allows for replacement into the title of the update with things like the update creator’s name, time, etc. | |||
false | payload.requestUpdate.titleContent.{token} |
String | ||||
false | payload.requestUpdate.title |
String | ||||
false | payload.requestUpdate.text |
String | ||||
false | payload.requestUpdate.updateDate |
Datetime | ||||
false | payload.requestUpdate.properties |
Object | ||||
false | payload.requestUpdate.properties.userName |
String | ||||
false | payload.requestUpdate.properties.isWorking |
Boolean | ||||
false | payload.requestUpdate.properties.images |
Array | ||||
false | payload.requestUpdate.properties.images[#] |
Object | ||||
false | payload.requestUpdate.properties.images[#].filename |
String | ||||
false | payload.requestUpdate.properties.images[#].mimetype |
String | ||||
false | payload.requestUpdate.properties.images[#].contents |
String | ||||
false | payload.requestUpdate.properties.attachments |
Array | ||||
false | payload.requestUpdate.properties.attachments[#] |
Object | ||||
false | payload.requestUpdate.properties.attachments[#].filename |
String | ||||
false | payload.requestUpdate.properties.attachments[#].mimetype |
String | ||||
false | payload.requestUpdate.properties.attachments[#].contents |
String | ||||
false | payload.requestUpdate.properties.disposition |
String | ||||
false | payload.requestUpdates |
Array | Request updates array of requestUpdate objects, for error messages and passing requests with multiple updates to a dealer system. | |||
false | payload.requestUpdates[#] |
Object | ||||
false | payload.requestUpdates[#].status |
String | ||||
false | payload.requestUpdates[#].createdDate |
Datetime | ||||
false | payload.requestUpdates[#].createdBy |
String | ||||
false | payload.requestUpdates[#].titleToken |
String | ||||
false | payload.requestUpdates[#].titleContent |
Object | ||||
false | payload.requestUpdates[#].titleContent.{token} |
String | ||||
false | payload.requestUpdates[#].title |
String | ||||
false | payload.requestUpdates[#].text |
String | ||||
false | payload.requestUpdates[#].updateDate |
Datetime | ||||
false | payload.requestUpdates[#].properties |
Object | ||||
false | payload.requestUpdates[#].properties.userName |
String | ||||
false | payload.requestUpdates[#].properties.isWorking |
Boolean | ||||
false | payload.requestUpdates[#].properties.images |
Array | ||||
false | payload.requestUpdates[#].properties.images[#] |
Object | ||||
false | payload.requestUpdates[#].properties.images[#].filename |
String | ||||
false | payload.requestUpdates[#].properties.images[#].mimetype |
String | ||||
false | payload.requestUpdates[#].properties.images[#].contents |
String | ||||
false | payload.requestUpdates[#].properties.attachments |
Array | ||||
false | payload.requestUpdates[#].properties.attachments[#] |
Object | ||||
false | payload.requestUpdates[#].properties.attachments[#].filename |
String | ||||
false | payload.requestUpdates[#].properties.attachments[#].mimetype |
String | ||||
false | payload.requestUpdates[#].properties.attachments[#].contents |
String | ||||
false | payload.requestUpdates[#].properties.disposition |
String | ||||
false | payload.message |
Object | Message object for passing direct message contents between customer and dealer users. | |||
false | payload.message.messageChain |
Object | ||||
false | payload.message.messageChain.localId |
String | ||||
false | payload.message.messageChain.remoteId |
String | ||||
false | payload.message.messageChain.chainType |
String | ||||
false | payload.message.messageChain.createdDate |
Datetime | ||||
false | payload.message.messageChain.createdBy |
String | ||||
false | payload.message.messageChain.active |
Boolean | ||||
false | payload.message.messageChain.properties |
Object | ||||
false | payload.message.messageChain.properties.userName |
String | ||||
false | payload.message.messages |
Array | ||||
false | payload.message.messages[#] |
Object | ||||
false | payload.message.messages[#].createdDate |
Datetime | ||||
false | payload.message.messages[#].createdBy |
String | ||||
false | payload.message.messages[#].messageText |
String | ||||
false | payload.message.messages[#].properties |
Object | ||||
false | payload.message.messages[#].properties.userName |
String | ||||
false | payload.message.asset |
Object | ||||
false | payload.message.asset.rentedAssetId |
String | ||||
false | payload.message.asset.equipmentAssetId |
String | ||||
false | payload.message.asset.serialNumber |
String | ||||
false | payload.message.contract |
Object | ||||
false | payload.message.contract.contractId |
String |
Transmission/Media Type
- Mailbox
- Web service
- LU6.2
- XML
- API
- PC to Client
Testing Procedures
Who To Contact
For the scheduling of your testing needs, please contact your local dealer Caterpillar CRS Representative to coordinate the needed testing with the appropriate team. If you are unfamiliar with your CRS Representative, you can request assistance from
Test Configuration
N/A
Sample Test Data
N/A
Production Information
Production Comments
N/A
Production Mailbox and Batch ID
N/A
Release Notes
While the Modification history gives an overview of the updates in each version, this is intended to flesh out what the additions mean for each subsequent release of this document.
Version 2.0
Moving from 1.6 (the previous release) to 2.0 adds several pieces of explanation to this document, a few extensions to contracts and invoices for multi-locale management, and several steps toward seamless integration to the extent possible with a dealer’s systems (RMS, CRM, etc.)
Error Architecture, Codes, and Messages
Added explanation of requirements around error responses and empty success messages. This does not change the API for any existing implementations.
Contract/Invoice Updates – asset model, currency, contract invoiceFrequency
To support model information on rented assets more completely (separating the category group / rental class short description from the equipment model) we are adding a model field to the contracts and invoices assetDetails array elements. (See items[#].assetDetails[#].model
in both invoice and contract/asset data definitions.)
To address multi-currency dealers, and the ability to invoice or write a contract in a currency other than the dealer’s primary currency, we’ve added a currency field to the invoice and contract data layouts.
To address a gap in this document, the invoiceFrequency value of ThirtyDays was added to the list of valid invoiceFrequency values for a contract.
Incremental Endpoint for More Frequent, Low-Impact Updates
An interim solution to getting closer to real-time updates. Depends on being able to quickly identify customers with updates so that the appropriate updates that need to be sent from the dealer system to the Cat Rental Store can be pulled in via the normal data pull APIs.
Realtime Integration
Specify a facility for passing realtime updates from a dealer system into the CRS Web Services, and also for managing real-time communication between customer users and dealer users to make that communication simpler for dealer users and customer users where integration is implemented.
Version 1.6
Moving from 1.5 (the previous release) to 1.6, we have added several fields that are optional in the CRS API implementation, but that supply features and functionality that will be leveraged by the CRS platform to more fully support your customers and your interaction with them. These features are:
Contract Division, Type, and Asset Purchase Price
To support tracking and notifying dealer personnel based on the division of a contract. If multi-division support is required by your dealership, please contact your Cat Rental Store Deployment Consultant for more information:
items[#].divisionId
- If present and populated, this indicates the division of the dealership managing the contract.
To support indicating to customers whether a contract is a rental or lease contract for eventual presentation to customer users:
items[#].contractType
- If present and populated, this indicates what type of contract this is. Current valid values are:
- Rental
- Lease
- RTO
- RPO
- Rental
- If the value of contractType is not one of those values, it will default to “Rental” and present as a standard rental contract.
- If present and populated, this indicates what type of contract this is. Current valid values are:
To support indicating to the customer what the asset buy-out price is currently for an asset that is on a lease that allows buy-out:
items[#].assetDetails[#].assetPurchasePrice
- If present and populated, this indicates the buy-out price for the asset if the customer would like to purchase this specific asset.
Version 1.5
Moving from 1.4 (the previous release) to 1.5, we have added several fields that are optional in the CRS API implementation, but that supply features and functionality that will be leveraged by the CRS platform to more fully support your customers and your interaction with them. These features are:
Reservations
To support the display of equipment reservations to the customer, we have added a flag to contracts indicating that a given “contract” is a reservation:
items[#].isReservation
- true indicates that this contract should be treated as a reservation, not a signed contract. False or not present both indicate a standard active contract for rented assets.
Contract Utilization
To support tracking asset utilization even when telematics for the asset at the beginning of the contract is not available, we’ve added a field to indicate what the lifetime usage of the asset was at the start of the contract:
items[#].assetDetails[#].startingOdometer
- If present and populated, this indicates the value of the usage indicator (in hours or mileage, depending on equipment type) when the contract began.
Contract and Invoice Rates
To better fit the rental business model, rates on individual items on contracts and invoices (e.g. attachments, tool kits, etc.) are no longer required. If they are not supplied, the charges for items with no rate are assumed to be included in the charge for the prime asset on rent on the contract.
Version 1.4
Moving from 1.1 (the initial release) to 1.4, in addition to clarifications and additional existing functionality description, we have added several fields that are optional in the CRS API implementation, but that supply features and functionality that will be leveraged by the CRS platform to more fully support your customers and your interaction with them. These features are:
Contract Billing Cycle
To support more robust presentation of the contract billing cycle, we added fields to the contract definition to support presentation of the billing cycle details to the customer:
items[#].invoicedThruDate
- invoice.billedDateEnd for the most recent periodic invoice on this contract
- This is used to calculate the billing cycle for this contract.
- invoice.billedDateEnd for the most recent periodic invoice on this contract
items[#].invoiceFrequency
- frequency of invoicing
- Enumerated list of billing frequencies that define the default length of an invoice period on this contract. The invoiceFrequency will default to “fourweek” but can be any of the following:
- day
- week
- month
- fourweek
- thirtydays
- quarter
- biweekly
- semiannual
- year
- day
- frequency of invoicing
items[#].billControl
- days from the start of the billable period after which a new invoice for the next billable period will be generated and sent to the customer
- This is used to determine when the next invoice will be generated.
- days from the start of the billable period after which a new invoice for the next billable period will be generated and sent to the customer
Asset-specific Information
To support additional asset states within a contract and provide a call-off confirmation number to the customer when one is available, we’ve adding four fields to the asset definition within the contract:
items[#].assetDetails[#].callOffConfirmationNumber
- reference number for an asset call off (null or missing if asset is not called off)
- once we get it in place, this will be offered to the customer when they see an asset that has been called off.
- reference number for an asset call off (null or missing if asset is not called off)
items[#].assetDetails[#].assetStartDate
- Date asset went on rent on this contract. If null or missing, assumed to be contract start date.
- This is primarily used to keep telematics information to just the time the customer has the machine, but may also be presented to the customer in the future.
- Date asset went on rent on this contract. If null or missing, assumed to be contract start date.
items[#].assetDetails[#].assetCallOffDate
- Date asset was called off (null or missing means it’s not called off.)
- This, along with callOffConfirmationNumber, allows for asset-level calloff status to be relayed to the customer.
- Date asset was called off (null or missing means it’s not called off.)
items[#].assetDetails[#].assetReturnedDate
- Date asset was returned to dealer (null until returned)
- We will use this to remove assets from view of the customer if they have been returned to the dealership but still remain on the contract for invoicing/business system reasons.
- Date asset was returned to dealer (null until returned)
PDF Document Support
To support document delivery to rental customers of the documents they have indicated they are most interested in being able to retrieve digitally, we will collect PDFs from your system, and based on the customer relationships you provision in the DMT, will allow users to download contract and invoice PDFs that are official and reflect your dealership. These PDFs will need to be generated, but we will retrieve them from your system when we do our daily pulls so that updates of the underlying information triggers updates of the PDF documentation as well.
Contracts:
items[#].pdfUrl
- URL of the PDF on your system. Our expectation is that PDF retrieval will require the same credentials as the API requires.
Invoices:
items[#].pdfUrl
- URL of the PDF on your system. Our expectation is that PDF retrieval will require the same credentials as the API requires.
Multi-Country Support
For both jobsites and dealer locations, we have added a country specifier to support multi-country dealers. Without those fields, the system assumes that the dealer is not multi-country, and that the country of any jobsites or dealer locations will match the country of the dealership itself.
Jobsites:
items[#].country
- 3 or 2 character code for the country of the jobsite location.
Dealer Locations:
items[#].country
- 3 or 2 character code for the country of the jobsite location.
Version 1.1
Initial release of this API documentation.