WIP - V3 Migration guide
The required changes from Offer V2 to V3 are relatively minor, compared to the effort needed to migrate from V1. Below is a summary of most changes.
Spec changes
The biggest change is that the spec now only contains the endpoints and models available for partners.
Operation Ids have been simplified, new information has been added about security schema and required permissions. Tags have been renamed to be better in line with standards. Error description has been simplified.
Headers for rate limiting and Offer expiration have been documented.
Simple structure changes
Some objects have been merged, as they detailed the same information. Some objects have been renamed. Any field referencing TariffZones has been removed. TariffZone is no longer an accepted input. Deprecated fields have been removed.
Headers
| Header | Old value | New value |
|---|---|---|
| Skip-Offers-Caching | true/false | Replaced by separate endpoints |
| ResponseType | SearchResponse/SearchResponseFull | - |
| Accept-Language | nob/nno/eng | nb/nn/en per Entur api guidelines |
Objects
| Old name | New name |
|---|---|
| AvailableFulfillmentMethod | AvailableFulfillment |
| PriceSummary | Price |
| RefType | ObjectRef |
| SearchWithAuthorityRequest | SearchAuthorityRequest |
| SearchZonesRequest | SearchGeoLocationRequest |
| SearchStopPlaceRequest | SearchGeoLocationRequest |
| ZonalValiditySummary | ZonalValidity |
Fields
| Object | Old value | New value |
|---|---|---|
| ApiError | error | title |
| ApiError | message | detail |
| OfferSummary | availableFulfillmentMethods | availableFulfilmentMethods (spelling change) |
| OfferSummary | - | salesPackageId |
| OfferSummary | - | salesPackageVersion |
| OptionalProduct | discountRight | discountRights, type change to array |
| PreassignedProduct | discountRight | discountRights, type change to array |
| PropertiesSummary | - | nuisanceFacilities |
| SearchResponse | - | notices |
| UnavailableProduct | - | name |
| ZonalValidity | - | See separate description |
Enums
Nearly all enum types have been removed, having been replaced by strings. This is to increase flexibility and bring the Offers API more in line with what is returned from JourneyPlanner. Lists of known values will be provided, however the client must implement fallback logic to handle unknown values. It is expected that new values will be added during the lifespan of this major version. We do not guarantee a grace period between introducing new values and using them.
The only enums remaining are those used as input, as well as those used when categorizing a Recommendation.
Renaming of enum values
To bring Offers more in line with the NeTEx standard, the following Enums have been renamed. Please note this includes both the actual enum used for both requests and string values returned in responses.
| Enum name | Old value | New value |
|---|---|---|
| UserType | YOUTH | YOUNG_PERSON |
| AccommodationFacility | FAMILY_COMPARTMENT | FAMILY_CARRIAGE |
| AccommodationFacility | RECLINING_SEAT | RECLINING_SEATS |
Merging of endpoints
The endpoints of /offers/v2/zones and /offers/v2/stop-places have been merged into one endpoint /offers/v3/search/geographical-location.
This endpoint supports searching by FareZones, StopPlaces or a mix. The endpoint also supports filtering on transport mode.
If the transport mode is absent, all transport modes will be considered unless both StopPlaces are rail stations.
The different combinations of inputs in SearchGeoLocationRequest are summarized below.
| From | To | Result |
|---|---|---|
| FareZone | FareZone | Same behaviour as /offers/v2/zones |
| StopPlace | StopPlace | Same behaviour as /offers/v2/stop-places |
| StopPlace | FareZone | Offers will automatically select the FareZone from the StopPlace with the same authority as the to FareZone |
| FareZone | StopPlace | Offers will automatically select the FareZone from the StopPlace with the same authority as the from FareZone |
Redesign of Traveller
Several fields on Traveller relating to customer identity and functionality specific to identified individuals were grouped into a new structure TravellerContext.
ExistingTicket on root level was removed, so the client no longer needs to differentiate between one and more travellers, except for cappingSpecification.
V2:
Code
V3:
Code
Customer identity
Multiple sources for customer identity are supported. Old fields have been removed.
| Old location | New location |
|---|---|
| customerId | travellerContext.customerIdentity[].customerRef (source: CUSTOMERS) |
| cappingSpecification.customerRef.accountBasedTicketingCustomerRef | travellerContext.customerIdentity[].customerRef (source: ABT) |
Preowned products
ExistingTicket has been moved from root request level to Traveller replacing productIds and renamed to OwnedRight.
FareContracts should be provided here, and have been removed from cappingSpecification, while cappingSpecification itself
has also been moved into OwnedRight.
Redesign of GeographicalValidity
PointToPointValidity now includes display names for the stop places. fromPlace and toPlace have been changed from plain strings to named references.
ZonalValidity now contains some new fields: fromZone and toZone with named references, and an unordered set of viaZones.
FromZone/toZone/viaZones will not be populated when a groupOfTariffZones is included.
Restructure UnavailableProducts
UnavailableProducts no longer guarantees the presence of serviceJourney, if that information is not available.
This means UnavailableProducts can be returned also from endpoints other than /offers/v3/search/trip-pattern. In addition, product name is included for display purposes.
Notices - Beta
Occasionally, some underlying services may not be responding. Previously, that error has been ignored and partial offers have been returned.
In order to help clients display information to the customers, a response may include an array of notices, describing potentially missing information.
Examples include, but not limited to, missing quota, seating or personalisation. It is up to the client to determine if this is useful.
Recommendations
The recommendations field in SearchResponse has changed from an array of Recommendation to a RecommendationResult object.
Recommendations are partitioned into two lists based on journey coverage. Partial recommendations still carry the combineWithToCoverEntireJourney field,
describing how to combine them with other recommendations to achieve full journey coverage. The field id has been added to Recommendation, while combineWithToCoverEntireJourney
now refers to this id rather than a whole Recommendation.
V2:
Code
V3:
Code
| Object | Old value | New value |
|---|---|---|
| AccommodationFacility | ANY_FACILITY_SET | ANY |
| DurationEnum | - | ANY |
| JourneyOrganizeAlgorithmEnum | FOR_EACH_AND_GROUPED | - |
| Recommendation | - | id |
| RuleSpec | mixinOffersWithHigherFlexibility | mixInOffersWithHigherFlexibility |
| RuleSpec | removeSplitRailReplacementOffers | - |
Default value changes
Default values have been updated to reflect the recommended approach.
| Field | V2 default | V3 default |
|---|---|---|
| RuleSpec.onlyIncludeRecommendedOffers | false | true |
| RuleSpec.mixInOffersWithHigherFlexibility | false | true |
| RuleSpec.mixInOffersWithOtherFacilitySets | false | true |
| RuleSpec.priceComparisonAlgorithm | BEFORE_SDR | TOTAL_PRICE |
| CategorySpec.typesOfRecommendation | - | CHEAPEST |
| CategorySpec.durationTypes | - | ANY |
| CategorySpec.fareClasses | - | ANY |
| CategorySpec.facilitySet | - | ANY |
Behavioural changes
Searching with existing ticket
In Offers V2, if the provided existingTicket referred to a zone not included in the trip, an exception was thrown. This has been changed to evaluating the trip as normal, which removes the necessity of the client knowing whether the previously owned zone is relevant.
Searching for passed departures
Searching for a departure which has passed will now result in an exception (404 Not Found) instead of empty offers.
Mode for alternative transport
When a rail service has been replaced, the actual mode will be returned instead of mode: RAIL
Enforcement of api restrictions
Multiple travellers in the same request identified with the same customer number will be rejected.
Empty arrays are no longer accepted as input in any field.