Beyond ordinary REST API with Inriver

REST APIs are known for their predictability. Most often this comes at a cost of less flexibility. But Inriver's REST API is not like most.

Inriver is a Product Information Management (PIM) system existing in the cloud. It provides businesses with workflows for content enrichment, planning and publishing. For those who sees the benefit, it can be the single source of truth as it can be integrated with businesses’ other systems, such as a Content Management System (CMS) or e-commerce solution. Today we write about one way we can integrate our other systems with Inriver, and that is using its REST API.

The REST API follows an earlier version of the Open API specification. It uses Swagger’s set of tools for visualizing and exploring the API. This powerful system means that a developer can quickly get an overview for each endpoint at a glance. And while using it, it behaves in a predictable way:

HTTP requests are used to interact with the API. GET is for fetching data. PUT is for updating. DELETE is for deleting. POST is used for adding data, most of the times. The API-documentation (powered by Swagger) details the format for the request as well as the expected response body. This means that any interaction available is documented. As an example on how to quickly see all the available channels with cURL, the request would look like this:

curl -X GET --header 'Accept: application/json' --header 'X-inRiver-APIKey:examplesecureuniquekey' ''

And the result would be something like this:

    "id": 1,
    "displayName": ”Webshop - Sweden",
    "displayDescription": "True",
    "entityTypeId": "Channel",
    "createdDate": "2022-01-01T08:00:00.0000000",
    "modifiedDate": "2022-01-01T08:00:00.0000000",
    "isPublished": true
    "id": 2,
    "displayName": "Webshop - Global",
    "displayDescription": "True",
    "entityTypeId": "Channel",
    "createdDate": "2022-01-01T08:05:00.0000000",
    "modifiedDate": "2022-01-01T08:05:00.0000000",
    "isPublished": true

So while there are endpoints for interacting with channels, media and different entities in a secure and standard RESTful way - there are also a couple of endpoints that are a bit more unique. These are the query and entities:fetchdata endpoints. Both takes POST-requests but are used for fetching data; query and entities:fetchdata.

The Query endpoint

From simple to more complex queries, this endpoint is used to build custom queries that may not be supported by the other endpoints. A major advantage of this endpoint compared to the others is that it supports operators. 

Operators are strings such as IsTrue, IsEqual, IsGreaterThan (and their counterparts), and can be used on entities, their fields and inbound/outbound relations. This enables a flexible and complex query building - but the response body is quite simple. Let’s run a basic form of query, and looking for any entities that does not have an ID of 1:

  "systemCriteria": [
      "type": "EntityTypeId",
      "value": 2,
      "operator": "NotEqual"

This brings a response with the following body:

  "count": 4,
  "entityIds": [

Using the query endpoint is a good way to find the required entities, but another endpoint is then needed to explore these entities in turn.

The flexible entities:fetchdata endpoint

While the query-endpoint is good for building complex queries to finding required entities, the entities:fetchdata is a powerful endpoint to structure what data is wanted from each entity. This is an endpoint that accepts POST-requests with a body containing some of the following keys:

entityIds* - array of ids 
objects* - string 
fieldTypeIds - string
inbound - json with keys
linkTypeIds - string
objects - string
linkEntityObjects - string
outbound - json with keys
linkTypeIds - string
objects - string
linkEntityObjects - string 
* required

This specifies that entityIds and objects are required, and the keys for inbound and outbound can contain a few keys of their own. Build a request accordingly would turn out something like this:

    "objects": "EntitySummary, FieldsSummary, FieldValues, Media, MediaDetails",
    "outbound": {
        "linkTypeIds":"NodeArticleSection, ChannelNodeProducts, ChannelNodeChannelNode",
        "objects":"EntitySummary, FieldsSummary, FieldValues, MediaDetails"
    "inbound": {
        "linkTypeIds":"ChannelNodeChannelNode, ChannelChannelNode",
        "objects":"EntitySummary, FieldsSummary, FieldValues, MediaDetails"

So what do each key actually mean? Here’s a quick overview:

entityIds are exactly that. Every piece of content in Inriver has an ID and are referred to as an entity ID. If there is a need to get a list of entities, the channel endpoint can be used to get available channels, which in turn can be used to get available entities for a specified channel. The endpoint /api/v1.0.0/channels gives a list of channelIds. This information gives access to a channelId that can be used to get entityIds with the endpoint /api/v1.0.0/channels/{channelId}/entitylist.  

objects are used for specifying what information to fetch for the entities. One such object, EntitySummary, gives the following information on an entity with the ID 10:

    "summary": {
      "id": 10,
      "displayName": "Acme Laptop",
      "displayDescription": "Excellent Laptop for developers.",
      "version": "1",
      "lockedBy": null,
      "createdBy": ”",
      "createdDate": "2022-03-18T13:00:00.0000000",
      "formattedCreatedDate": "2022-03-18 13:00:00",
      "modifiedBy": ””,
      "modifiedDate": "2022-03-19T08:00:00.0000000",
      "formattedModifiedDate": "2022-03-19 08:00:00",
      "resourceUrl": ”",
      "entityTypeId": "Product",
      "entityTypeDisplayName": "Product",
      "completeness": 0,
      "fieldSetId": "ProductLaptop",
      "fieldSetName": "Product Laptop",
      "segmentId": 0,
      "segmentName": "Default"

Available objects are: EntitySummary, FieldsSummary, FieldValues, SpecificationSummary, SpecificationValues, Media och MediaDetails. The specific fields provided by each object can be found at!/Entity/Entity_FetchData. To get data for multiple objects is as easy as specifying each object in the same string, separated with a comma.

fieldTypeIds are the fields to select for the fetch-request. Specifying a fieldTypeId will filter out any other fields not corresponding to that ID. This means that such objects such as FieldsSummary and FieldValues will be affected if this key is used. Not specifying and field type will fetch any relevant fields for the entities in the request. Specifying multiple field types is possible. Just type them in a single string, comma separated: "fieldTypeIds":"ProductName, ProductDescription”.

inbound is a way to fetch entities where a fetched entity is included. For example a product category ”Laptops” may have included a product ”Acme Laptop”, in this instance the ”Laptops” entity is an inbound relation. To specify what inbound relations that is wanted, the key linkTypeIds are used. Examples on IDs are ChannelChannelNode, ChannelNodeProducts. Just as for the original request, an objects key is used on the inbound-specification to specify what information is wanted for the inbound links.

outbound is a way to fetch entities which the current entity includes. The specification is the same as for the inbound-key, where the keys linkTypeIds and objects are used.

This was a quick overview on how to use the REST API in Inriver. If you want to see the API just at a glance, look at Inriver community’s overview. Having a RESTful API at hand is a great way to extend the service that Inriver provides. It means that we can use the power of a PIM and the flexibility of SilverStripe CMS in a package along with an e-commerce solution. While some REST API’s can be limiting in only providing a few rigid endpoints - the Inriver REST API provides a more extensible solution through the query and entities:fetchdata endpoints.

Photo by cottonbro from Pexels

Vad kan vi göra för dig?

Har du en bra idé eller ett problem som du behöver hjälp att lösa?
Ta gärna kontakt med oss för att se vad vi kan göra för er, och hur vi kan hjälpa er!

Kontakta oss