Inventory quickstart


Inventory deals with quotas, a quota is a limit on the number of instances of something that can be reserved at once. A quota will usually have some sort of geographic component, and it will always be associated with a particular departure. For example, one could define a quota on regular tickets for the train leaving Bergen for Oslo at nine o'clock in the morning on the 1st of January 2019. This quickstart will show how to insert your first quota for a fictional transportation company.


The Inventory requires a Bearer Token in the Authorization header created by the Entur Authentication server for every request.

Creating departure information

Quotas are added on specific departures. A departure is a single instance of a train or other vehicle leaving its first passenger-carrying stop at a predetermined time and date. A departure is always associated with a line. A line is an ordered list of physical stops that may be visited during a journey. Whether a train actually stops at a given stop on a line is not known by the Inventory module. The Inventory is not the source module for departures and lines, but it needs to have an up-to-date view of both in order to function properly.

Inserting a line

Before one can define a quota one needs departure information. A departure is dependent on knowing which stops the departure could possibly stop at, the line for the departure. All lines are defined in the journey planner, but also have to be defined in the Inventory module, as it is required to be able to calculate the stock between an origin and a destination.

The identification used for the line should be the same as in the journey planner module. The stops are given on the format from the National stop register, in an ordered list from start to end. It is possible to use a line in the reverse order as well, this is defined when inserting a departure, so it is not necessary to add the inverse line.



  "id": "ABC:Line:1",
  "version": 1,
  "stops": [




In this example we imagine there exists a line in the journey planner with the id "ABC:Line:1". The version is set to 1 as this is the first version of this line added to the Inventory. On this line we imagine three stops, "Oslo S", "Lillestrøm stasjon" and "Kløfta stasjon", which have the NSR-codes "NSR:StopPlace:337", "NSR:StopPlace:451", and "NSR:StopPlace:553".

After this request is processed, we should receive a 201 Created with the entity. The line is now ready to be referenced from a departure.

Inserting a departure

The departure is the key in the inventory. A departure is a single instance of a train or other vehicle leaving its first passenger-carrying stop at a predetermined time and date. A departure is always associated with a line.

The identification of the departure is the original dated service journey that is created in the timetable module. The line id is the same that was defined when inserting the line. One also have to define which direction of the line is used for the departure. If the departure uses the line in the order defined when inserting the line information, the invertedDirection field is set defined as false. If you want the departure to use the line in the opposite order the invertedDirection field is defined as true.



  "id": "ENT:DatedServiceJourney:2838",
  "lineId": "ABC:Line:1",
  "invertedDirection": "false"



In this example we imagine there exists a departure  "ENT:DatedServiceJourney:2838" in the timetable. We define this departure to use "ABC:Line:1" in the same direction as above, starting at Oslo ("NSR:StopPlace:337").

After this request is processed, we should receive a 201 Created. The entity including line information is returned, and the departure is now ready for use.

Creating quota configurations

A quota configuration defines in part how the quota should behave. See the quide on quota configurations for details.

Creating a simple quota configuration

One might imagine a quota where the resource to limit is sold seats. In the following section we will create a simple quota with a stoplist. A quota with a stoplist release the resource when a reservation is not using it. If a user reserves the resource in the first half of a journey (e.g. Oslo to Lillestrøm), it is still available for others in the second half (e.g. Lillestrøm to Kløfta). We will now create a quota-configuration where the useStoplist-flag is true.


  "name": "ABC:QuotaConfig:Test1",
  "nestingRuleId": 1,
  "validFrom": "2019-01-01T00:00:00Z",
  "validTo": null,
  "useStoplist": "true"




The quota configuration will be assigned an unique id that is returned in the response.

Creating a quota

Inserting basic quota

Now we have all the necessary information to create our first quota. 

In this example we create a quota for the product "ABC:PreassignedFareProduct:Ticket", with 10 available entities. We do not define anything in the "ods", as this is more complex behaviour. You can read more about this in the quides section. 

We use one of the quota configurations (id 8) that was retrieved in the last step, the one with "useStoplist" set as true. What this means for this quota is that you have 10 available "ABC:PreassignedFareProduct:Ticket" between each stop in the stoplist. The stoplist used is the one associated with the departure "ENT:DatedServiceJourney:2838".



    "quota": 10,
    "products": ["ABC:PreassignedFareProduct:Ticket"],
    "ods": [],
    "quotaConfigurationId": 8,
    "datedServiceJourneyId": "ENT:DatedServiceJourney:2838"




Congratulations! You have inserted your first quota!

Table of contents





Quota configurations



Dated Service Journeys are the basic building block in the inventory. Quotas and reservations are both added to a dated service journey.







Dated Service Journeys

A dated service journey represents a departure on a specific date. It contains the following fields:

  • id, the id for the dated service journey, e.g. ENT:DatedServiceJourney:905144

  • invertedDirection, indicates which direction this journey travels, true or false

  • lineId, the id of the line this journey travels on

The dated service journey id is defined by Entur's timetable service.


A line is a sequence of stop places that a dated service journey travels, it contains the following fields:

  • id, the id for the line, e.g. NSB:Line:21

  • version, the version of this line, e.g. 1

  • stops, the list of stop places that is included on the line, e.g. NSR:StopPlace:337, NSR:StopPlace:451, ...



A quota describes the limit of a resource, e.g. tickets on a specific dated service journey. Quotas are used to calculate the available stock on a dated service journey.















A quota consists of the following information:

  • quota: The amount of quotas specific to this quota.

  • products: The products specfic to this quota.

  • ods: The origin and destination pairs for this quota.

  • quotaConfiguration: Reference to the static configuration used by this quota.

  • datedServiceJourney: The dated service journey this quota applies to.

  • purchaseWindowStart: The start of the purchaseWindow on the associated quota

  • purchaseWindowStop: The end of the purchaseWindow on the associated quota



All reservations made must belong to a defined departure, which means that a line must also be defined.









A reservation is a claim on some of the availability of something, across a distance. A reservation must have a departure, a valid origin and destination on this departure, and one or more reservation lines. Reservation lines points to the product to reserve, a status, and the amount. This means a reservation can reserve multiple products.


A reservation have a status indicating where the reservation is in the purchase. A status also indicate how the reservation should affect the calculation of stock. A reservation can one of the following statuses:


Draft is a "soft-reservation" status. This means that whenever a user is in the process of buying a product we reserve the product with the status DRAFT. All reservations with DRAFT status will affect stock calculation similarly as reservations with status CONFIRMED. This way we're protected from overselling products and the customer is guaranteed their selected products after purchase.

Reservations with status DRAFT can only change status to either EXPIRED or CONFIRMED.


If a customer decides not to complete a purchase, all soft-reservations made by the customer will eventually expire. When a reservation expire all reservation lines change status to EXPIRED. This means that the products are no longer reserved and the reservations won't affect stock calculation.

Reservations with status EXPIRED can not change to any other status.


CONFIRMED means the reservation is confirmed by either a successful transactions or some other way. Confirmed reservations can no longer expire and will affect stock calculation. 

Reservations with status CONFIRMED can only change status to CANCELLED.


If a customer cancels a confirmed reservation the status changes to CANCELLED. Cancelling a reservation is described more in detail below. 


When a reservation is cancelled a releasing reservation is made to release the products. Cancelled and releasing reservations are described more in detail below.

Possible reservation status transitions


Cancelling a reservation

To cancel a reservation it must exist in Inventory and have the status CONFIRMED. Reservations with any other status can not transition to a cancelled status.

When a reservation is cancelled the status changes to CANCELLED and the products made available again. Just making the originally reserved products available again can create situations where the price presented to customers change after a cancellation because there is now more lower priced products available. To prevent this from happening it's possible to configure what product to add back after cancellations. 

When adding products back, a new reservation is made, the status RELEASING, and a negative amount to negate the original reservation. 







The stock service is used to calculate available stock, meaning the amount of available resources that are constrained by quotas on the departure. The query for available stock is on a given dated service journey between two stop places.

The result displays the available stock on the leg between the starting and end stop place for that journey.

The stock response contains the following fields:

  • datedServiceJourney: The id for the given dated service journey

  • origin: The starting stop place of the leg

  • destination: The destination stop place of the leg

  • organisation: The owner of the departure

  • stock: A list of available stock components

The stock components can either be a root node of a nesting tree, or a simple quota without any nesting.

Simple quotas

These components contain the two following fields:

  • products: A list of products that the quota constrains
  • leftInQuota: The remaining amount on this quota

Nesting tree nodes

The fields of a nesting tree node are somewhat different whether this is a parent-node or a leaf-node. Only leaf-nodes have a quota associated with it.

Parent nodes has the following fields:

  • nestingGroup: A name of this nesting rule

  • aggregatedAvailability: The maximum amount that can be reserved of quotas associated with decendants of this nesting rule

  • priority: The priority for nesting rule

  • components: A list of nesting rule children

  • consumptionRule: The consumption rule set on the nesting parent

  • selectionRule: The selection rule set on the nesting parent

Leaf nodes has the following fields:

  • nestingGroup: A name of this nesting rule

  • aggregatedAvailability: The maximum amount that can be reserved of this resource, including possible amounts that can carry over to nested, higher prioritized, sibling components 

  • priority: The priority for nesting rule

  • products: A list of product ids for the quota associated with the nesting rule

  • leftInQuota: The remaining available amount of the resource

  • purchaseWindowStart: The start of the purchaseWindow on the associated quota

  • purchaseWindowStop: The end of the purchaseWindow on the associated quota

The fields aggregatedAvailability and leftInQuota are set to zero if the associated quota is outside its purchaseWindow.

Quota configurations







Quota configurations are static configuration data that influence/determine quota behavior. The general idea is that quotas on a departure are assigned to the quota configuration that gives the desired behavior, thus quotas does not have to repeatedly define the same configuration.

Currently we have defined 4 different behaviors which are defined by two binary properties: a boolean property use_stoplist and the presence of an origin-destination pair in the od-list defined on each quota.

Use stoplist Od-list on quota Resulting quota behavior
false Empty Sales quota
true Empty Stoplist quota
false Non-empty Point-to-point quota
true Non-empty Combined stoplist quota

Sales quota

A sales quota is a quota that is not reusable. That means the resource/product is not released after a passenger has disembarked. Traditional examples are sleeping cabins that are booked for the entire journey, even if the cabin is booked between intermediary stations.

Stoplist quota

A stoplist quota is used for reusable resources that are released after a passenger disembarks. Typical examples consist reusable resources such as seats and limited ticket groups (as part of yield management). The quota determines the maximal number of the products that can be reserved between any two stations.

Point-to-point quota

A point-to-point quota is like a sales quota, except it only applies to reservations where the origin and destination appears in the od-list defined on the quota.

Combined stoplist quota

A combined stoplist quota is used for limiting the total reservation amount between some selected stations. A common example is that the train between Oslo and Trondheim experience a lot of passengers that both embark and disembark on stations around Lillehammer. This will reduce the available number of seats/tickets for travellers between Oslo and Trondheim which are more profitable. By applying a combined stoplist quota with a od-list [ (Brumundal, Kvitfjell) ], and a low quota-amount of e.g. 10 for product "CheapTicket", we allow for relatively cheap tickets to be made available to long travellers. This means that the total number of cheap tickets for travellers between e.g. Moelv and Hunderfossen can never exceed 10, and we retain the rest of the cheap tickets for long-distance travellers.





The inventory supports the concept of nesting for yield optimization. This allows for similar tickets to be sold at different price levels, typically this is done to allow early birds to acquire the cheapest tickets.  Early determination of ticket demand allows for better planning and optimization, like adding extra departures just before christmas or a grand concert, or using smaller trains in periods where you know few people will be travelling.

The inventory organize the different nesting rules in a tree structure called a nesting tree.

Example nesting tree:

This nesting tree includes 5 nodes with a root-node Ticket, and 3 leaf-nodes OrdinaryTicket, DiscountTicket1 and DiscountTicket2. The parent nodes, like the DiscountTicket node, are a grouping of nesting rules, and as a parent node it contains a selection rule and a consumption rule.


All nesting rules has a priority which determines ordering among siblings in the tree. In the above example, the rules could have the following priorities:

  • Ticket priority=1
    • OrdinaryTicket priority=1
    • DiscountTicket priority=2
      • DiscountTicket1 priority=1
      • DiscountTicket2 priority=2

Quotas with nesting rules in the same tree can be overspended. That is, it is possible to consume more than the quota for OrdinaryTicket, the overflowing amount will then be deducted from the stock of cheaper tickets. This is the primary function of having nodes in the same nesting tree.

If there had been another sibling GroupTicket (priority=3) of OrdinaryTicket and DiscountTicket, the order of recipients of overspended consumption from OrdinaryTicket would be:

  1. GroupTicket
  2. DiscountTicket2
  3. DiscountTicket1

Only leaf-nodes are associated with quotas, when the DiscountTicket (parent) node receive overspended consumption it forwards it to its children. If one of these children are parent nodes this is repeated, and the nodes are traversed from highest priority to lowest. 

Selection rule

The selection rule is a hint to the offers module of whether the different child price levels should hide each other. The following two values are allowed:

  • COMBINED - The combined selection rule is a hint to offer tickets as they appear. If the end customer wants 4 tickets, and 5 Discount1 and 2 Discount2 are available he/she should be offered 2 Discount2 tickets and 2 Discount1 tickets.
  • SINGLE - The single selection rule is a hint that the nesting rules should hide each other. That is, the end customer should be offered only one price level for all tickets. Thus if the customer wants 4 tickets, and 5 Discount1 and 2 Discount2 are available, the customer should be offered 4 Discount1 tickets. There is not enough Discount2 tickets available, therefore the Discount1 price level has hidden the Discount2 level.

The value of the selection rules does not influence counting in inventory.

Consumption rule

The consumption rule affects how reservations in inventory consumes the different price levels.

  • DIRECT - A reservation of a product is counted as a reservation of a product as long as the reservation amount does not surpass the associated quota. Any overflowing amount is counted as consumption towards quotas with a higher associated priority. 
  • BY_PRIORITY - A reservation of a product is counted as a reservation of the product with the highest priority in the same group. That is, given 5 available DiscountTicket1 and 5 DiscountTicket2, a reservation of 3 DiscountTicket1 and 2 DiscountTicket2 would have the same result as a reservation of 5 DiscountTicket2. Thus, unless DiscountTicket2 is "filled", there is always 5 DiscountTicket1 available.
The API reference(s) can be found here: