OSDM Version 3.8 Compliance for Retailer, Distribution and Inventory Systems in Sweden
Background
The National Distribution System (NDS), which connects carriers and retailers in the Swedish ecosystem through the OSDM standard, has now been in production for two years.
At the time of implementation, version 3.0 was selected as the “go-to version.”
During these two years, the OSDM standard has evolved and matured, and several systems have adapted to the standard. To remain compliant with the market and to benefit from new functionality, Samtrafiken, together with major stakeholders, has now decided to upgrade to version 3.8.
At this stage, the upgrade does not introduce new functionality. Its purpose is to align NDS with the latest version of the standard and enable future functional enhancements.
Time plan
The upgrade will take place during Q3 and Q4 2026. There will be a six-month transition period during which both versions will be available in parallel. The transition period will start when the new version is deployed in production.
The new version will also be available in the prelive environment to support development and testing. Planned to first week of October.
More details will be communicated to all stakeholders as they become available.
Introduction to the document
This page describes what to do in retailer, distribution and inventory systems connected in the Swedish eco-system.
The first section describes MVP changes that must be handled to be OSDM version 3.8 compliant in the Swedish eco-system.
NB: More changes are on property/item level about nullable, mandatory and minItems. A way to identify these is to run schema validation in IMS and DS to investigate any more formal problems.
To say that the inventory system is 3.8-compliant, more adoptions is needed, but it is up to the provider to serve DS with this information. Also DS need to handle these new endpoints/objects to expose them to retailers. This is stepp 2 stuff in the bottom of the page.
MVP changes (must do)
All existing objects/attributes that are deprecated in 3.8 must be delivered in parallel with the replacement object/attribute
HTTP Header Changes
Request Headers
To use OSDM 3.8, all requests must include an Accept header specifying the version:
Accept: application/vnd.uic.osdm+json; version=3.8
To make this backward compatible the Accept headers without this, default version 3.0 is assumed.
Response Headers
All responses must include a versioned Content-Type header:
Content-Type: application/vnd.uic.osdm+json; version=3.8.0
Returning Content-Type with patch version, eg. 3.0.7, is allowed but not mandatory.
A response must not be returned in a different major or minor version than requested.
Structured Error Handling (RFC 7807)
Errors
Errors are now returned in an extended Problem-object. New attributes are:
code
pointers
In code, the code of the error is returned. ExampleVALIDATION_ERROR.
In pointers a pointer to the request or response can be returned to point out the element or list item that caused the error.
"problem": {
"code": "urn:uic:problem:MALFORMED_REQUEST",
"type": "https://osdm.io/errors/malformed_request",
"title": "Request failed schema validation",
"detail": "The request does not validate the OSDM OpenAPI schema specification",
"status": 400,
"pointers" : [
{
"requestPointer": "#/passengerSpecifications[0]/age"
}
]
}The new items are optional, so they might be omitted in responses.
Warnings → Problems
Old warning structure is deprecated and must still be returned together with the new problem structure. Pointers are optional, but it is good practice to return it if possible.
{
"warnings": {
"warnings": [
{
"code": "NO_OFFERS_FOUND",
"type": "https://example.com/warns/no_offers",
"detail": "No offers found",
"instance": "offers/offer1234"
}
]
},
"problems": [
{
"code": "NO_OFFERS_FOUND",
"type": "https://example.com/probs/no_offers",
"detail": "Could not find any offers",
"pointers": [
{
"requestPointer": "#/tripOfferSpecification[0]"
}
]
},......problems.code
Code of the error/warning must be returned.
The code shall have an urn-prefix
General OSDM error codes urn:uic:problem:[code]
Common codes within sweden urn:x_swe:problem:[code]
Operator-specific codes urn:x_swe_VR:problem:[code] . A code specific for carrier VR
Example: urn:x_swe:problem:VALIDATION_ERROR
problems.pointers
To return pointers is optional for the IMS but it is good practice and recommended. Especially to point out the trip in an offer response that has a problem. Then the retailer can explain to the user the reason why offers are missing on some trips.
Passenger Identity (contactDetail)
Keep deprecated email and phoneNumber in existing PersonDetail
passangerDetail.emailalso provided inpassengerDetail.contact.emailpassangerDetail.phoneNumberalso provided inpassengerDetail.contact.phoneNumber
Change appliedReductions to CardReference
Offers
AdmissionOfferPart.appliedReductionCardTypeis deprecated but shall still be used as is.appliedPassengerTypes.appliedReductionsis new and MUST be used from all IMS’s when a discount is applied.code
number
issuer
type
"admissionOfferParts": [
{
"summary": "Admission offer part",
"appliedPassengerTypes": [
{
"passengerRef": "Adult",
"type": "ADULT",
"description": "Student ST",
"tripCoverage": {
"coveredTripId": "aedd18a2-9f9c-479f-bb2b-7aac3cbb4b6c",
"coveredLegIds": [
"747c6e47-d02e-4bb1-8c79-ce6436d67970"
]
},
"appliedReductionCardTypes": [
{
"code": "SWE_STUDENT",
"issuer": "urn:x_swe:carrier:nnn",
"name": {
"id": "9d588cc6-f4df-4e94-a238-baf5c7eb3a70",
"text": "Student in Sweden"
}
}
]
}
],
"appliedReductionCardTypes": [ <-- Depreceated
{
"code": "SWE_STUDENT",
"issuer": "urn:x_swe:carrier:nnn",
"name": {
"id": "9d588cc6-f4df-4e94-a238-baf5c7eb3a70",
"text": "Student in Sweden"
}
}
]
}
]Booked offers
Booked offer parts
appliedReductionCardTypeis deprecated but shall still be used as is.appliedPassengerTypes.appliedReductionsis new and shall be used and MUST be used from all IMS’s when a discount is applied. .code
number
issuer
type
"admissions": [
{
"summary": "booked admission offer part",
"appliedPassengerTypes": [
{
"passengerRef": "93ac4c8a-aee9-47a8-9b1f-b4660075b806",
"type": "ADULT",
"description": "Student",
"tripCoverage": {
"coveredTripId": "aedd18a2-9f9c-479f-bb2b-7aac3cbb4b6c"
},
"appliedReductionCardTypes": [
{
"code": "SWE_STUDENT",
"issuer": "urn:x_swe:carrier:nnn",
"name": {
"id": "d12fc320-7d15-4959-8710-d230bf13ee93",
"text": "Student in Sweden"
}
}
]
}
],
"appliedReductions": [ <-- Depreceated
{
"code": "SWE_STUDENT",
"issuer": "urn:x_swe:carrier:nnn",
"type": "REDUCTION_CARD"
}
]
}
]Deprecated confirmabelUntil
Retailer uses booking.confirmationTimeLimit instead.
IMS continues returning deprecated confirmableUntil.
Provisional refund amount
To avoid negative provisionalAmount a new attribute booking.provisionalRefundAmount is added. It describes the refund amount the customer is entitled to. provisionalAmount is 0 when provisionalRefundAmount is set
Allow fulfillments in prebooked state
This is already the case for SJ-bookings. Probably nothing to do.
Deprecate fulfillment media type ALLOCATOR_APP
ALLOCATOR_APP is replaced with DISTRIBUTOR_APP and RETAILER_APP . All three must be handled.
Deprectate isReservationRequired
AdmissionOfferPart.isReservationRequired and Admission.isReservationRequiredare deprecated.
Use minGroupItemsToBeBooked in reservationRelation instead. Both in offers and bookedOffers.
Deprecated appliedReductions on admission level
For retailers, stop using appliedReductions on offer part level. Use appliedPassengerTypes.appliedReductions instead. IMS need to provide both.
Add graphical reservation indicator for booking context
For offers: reservationOfferPart.supportedPlaceSelectionFlows is added to indicate how places can be selected or not.
For booking: reservations.supportedPlaceSelectionFlows is added to indicate how places can be selected or not.
MANUAL_PLACE_SELECTION_WITH_FEE: Manual/graphical place selection. A seat selection fee is charged for certain places. /availabilities/vehicle-place-map must be called before the /bookings call.
MANUAL_PLACE_SELECTION_WITHOUT_FEE: Manual/graphical place selection. No seat selection fee is charged for certain places. /availabilities/vehicle-place-map must be called before the /bookings call.
AUTOMATIC_PLACE_SELECTION: Automatic place selection based on selected accommodation (sub) types and place properties (see BookingRequest.placeSelections[].accommodations[]). It is not necessary to call /availabilities/* before the /bookings call.
AUTOMATIC_PLACE_SELECTION_NEARBY: Automatic place selection nearby a given place. /availabilities/nearby must be called before the /bookings call.
AUTOMATIC_PLACE_SELECTION_PREFERENCES: Automatic place selection based on available place preferences. /availabilities/preferences must be called before the /bookings call.
Setmap corrections
Ignore isSelectable on PlacePossition, use status istead to know if a place is FREE or not.
isSelectable stays on compartment level for complete compartment sales.
zOrder in LayoutCoordinates
layouts.places.coordszOrder is changed from string to integer. Breaking and must be handled for all parties.
Compartment number
booking.bookedOffers.reservations.placeAllocation.reservedPlaces.compartmentNumber is new and can be used to identify compartments when making complete compartment reservations.
compartmentNumber:
description: |
Compartment number as indicated at the compartment in the coach. A compartment number must be set if the compartment is selectable as a whole only.
type:
- string
- 'null'
examples:
- "C1"
- "6"
- "61-66"New end-point PATCH /bookings/{bookingId}/passengers (Added 2026-05-18)
This endpoint is not mandatory in MVP, but very desirable for IMS’s to implement.
To make bookings for large travel parties easier, there is a need for retailers to implement this bulk-update endpoint. Today, the client must call DS once for each passenger when adding personal details to the booking. This can take a long time and causes timeouts for large bookings.
The endpoint takes a list of passenger details and updates all passengers in one call.
It is desirable that all IMS systems have this end-point available from the beginning since DS will not take the list of passengers and make individual calls for each passenger to an IMS system.
Refund offer breakdown (Added 2026-05-18)
To enable informative UX at refund, retailers ask for the refundOffers.refundOfferBreakdown.
With refundOfferBreakdown, it is possible to show the purchaser/agent the refund value on each bookedOfferPart in the booking including fees.
DS and Samtrafiken IMSs can already handle refundOfferBreakdown, but call it refundOfferBreakDown. This must be corrected in version 3.8.
{
"refundOffers": [
{
"id": "779bcf1d-ef26-4ccb-b4c5-fcf1f7167015",
"summary": "Refund offer",
"createdOn": "2026-05-18T09:47:44.7966748Z",
"validFrom": "2026-05-18T09:47:44.7966748Z",
"validUntil": "2026-05-18T09:57:44.7966748Z",
"status": "PROPOSED",
"refundOfferBreakdown": [
{
"refundFee": {
"vats": [
{
"countryCode": "SE",
"amount": 538,
"scale": 2,
"percentage": 6.0
}
],
"currency": "SEK",
"amount": 9500,
"scale": 2
},
"refundableAmount": {
"vats": [
],
"currency": "SEK",
"amount": 0,
"scale": 2
},
"bookingParts": [
{
"id": "d182f9b4-654e-43f4-a09c-bb961e68b56d"
}
],
"fulfillmentId": "d182f9b4-654e-43f4-a09c-bb961e68b56d"
}
]
}
]
}Step 2
To say that the system is OSDM version 3.8 compatible these parts must be taken care of.This is not needed to go live but is critical for DS to update soon after launch or simultaneously. Underlying IMS may have these features and want to propagate them to retailers.
Add GrantedReductionAmounts
To make it possible for the retailer to show in detail the discounted amount of each reduction-type in the offer/booking.
Add grantedReductionAmounts in offers parts and booked offers parts for admission, reservation and ancillary types.
Relation between fulfillment and leg
Make it possible to point out fulfillment on leg-level for through fare admissions .
TripCoverage is added to fulfillment to makt his clear.
Allow fulfillments without content
When the distributor generates the document on behalf of the provider.
A new attribute to the fulfillment is added contentComplete. The attribute indicates whether the fulfillment has all documents or parts generated (if any needed) or they are still pending generation.
Add selection fee to seat map
To make it possible to show an extra fee for specific compartments/seats in the placemap a selectionFee attribute is added to Compartment and PlacePosition.
Support for coach deck layouts
New endpoints is created for place-map. These end-points is currently not used but shall be available to be 3.8-compliant. Important is that deprecated end-points keep working.
GET /coach-deck-layouts
GET /coach-deck-layouts/{layoutId}
POST /availabilities/vehicle-place-map
Migrating seat map to version 3.8 is subject to further investigation.
Generalize add/remove reservations and ancillaries
Currently there are separate endpoints to manage reservation and ancillary offerParts. Two generalized endpoints replaces four endpoints in the old specification
POST /bookings/{bookingId}/booked-offers/{bookedOfferId}/offer-parts
DELETE /bookings/{bookingId}/booked-offers/{bookedOfferId}/offer-parts
Depreacted /reservations and /ancillaries
Important that deprecated endpoints keep working as today.