Table of Contents

Apply a Cabin Number (Package)

See Booking flow for the end-to-end lifecycle.

Endpoint: /bookings/create/package/{:sessionId}/cabin-numbers

METHOD: POST

Books specific cabins on a held booking, replacing the guarantee cabins it was created with.

Call List Available Cabin Numbers first — a cabin number that has not been offered for that grade is rejected. Apply this before confirming; once the booking is confirmed the cabins are fixed.

Path Parameters

Name Type Required Description
sessionId string (UUID) Yes Session returned by /search/packages. Must be a package session and hold a booking.

Query Parameters

Name Type Required Description
user_key string Yes Unique key associated with the calling agency.

Request Body

Field Type Required Description
cabins array of objects Yes One entry per cabin to assign. Cabins left out keep whatever they already hold.
cabins[].cabinId number Yes id of the cabin on the booking response. Each cabin can appear at most once.
cabins[].cabinNumber string No Cabin number from the available list for that cabin's grade, or null to release the cabin back to a guarantee. Omitting the field is the same as sending null. Matched case-insensitively; surrounding whitespace is ignored. The same number cannot be requested for two cabins. An empty or blank string is rejected — send null.

Example

Request

curl --location '{:apiBase}/bookings/create/package/{:sessionId}/cabin-numbers?user_key=abcdef' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer XXXXXXXX' \
--data '{
    "cabins": [
        {
            "cabinId": 1,
            "cabinNumber": "313"
        }
    ]
}'

Response

{
    "sessionId": "eb86ca32-e42e-4ad0-aed4-f523cf549857",
    "market": "NO",
    "currency": "NOK",
    "departureDate": "2026-01-10T20:30:00",
    "arrivalDate": "2026-01-16T09:00:00",
    "departurePort": "BGO",
    "arrivalPort": "KKN",
    "shipCode": "NK",
    "embarkationNotification": null,
    "guests": [
        {
            "id": 1,
            "type": "ADULT"
        }
    ],
    "cabins": [
        {
            "id": 1,
            "code": "I2",
            "cabinType": "Inside",
            "cabinNumber": "313",
            "guests": [1]
        }
    ],
    "addons": [],
    "excursions": [],
    "supplementalTours": [],
    "packageCode": "ABCDEF",
    "packageStartDate": "2026-01-08T00:00:00",
    "packageEndDate": "2026-01-16T00:00:00",
    "packageDeparturePort": "OSL",
    "packageArrivalPort": "KKN",
    "priceBreakdown": {
        "totalPrice": 5140.0,
        "cabins": [
            {
                "code": "I2",
                "guests": [
                    {
                        "guestId": 1,
                        "price": 5140.0
                    }
                ]
            }
        ],
        "addons": [],
        "excursions": [],
        "supplementalTours": []
    }
}

Fields

The response body is identical in shape to Create Package Booking — see its Fields table for the full field reference. cabins[].cabinNumber now carries the allocated cabin.

Errors

See Error model for response-body shapes across status codes.

Status Cause
400 user_key is missing; the body fails validation (see below); a cabinId is not a cabin on the booking; the available numbers for that cabin's grade have not been listed in this session; a cabinNumber was not among them; or the cabin's grade does not correspond to specific cabins.
404 The session does not exist or has expired.
409 The session is not a package session; no held booking exists in it yet; or the cabin was taken before the request arrived.

Validation rules. A 400 is returned when any of these are not met:

  • cabins must be non-empty.
  • Each cabinId must address a cabin on the booking.
  • No cabin may be given two numbers, and no number may be requested for two cabins.
  • Each cabinNumber must either be null, or appear in the available list for that cabin's grade. Blank strings are rejected.

Releasing a cabin. Send null as the cabinNumber to give a chosen cabin back and return to a guarantee cabin, assigned before departure. No prior call to List Available Cabin Numbers is needed to release, and the response carries cabinNumber: null for that cabin. Changing directly from one cabin to another needs no release first — apply the new number.

List before every apply. The available numbers are recorded against the session when you call List Available Cabin Numbers, and are discarded once an apply succeeds. So each POST must be preceded by a GET for every grade it references, in the same session — including when you come back to assign a second cabin or change an earlier choice. Assigning cabins across two grades in one POST means calling the GET once per grade first, and those GETs must be made one at a time. A retried POST whose first attempt actually succeeded returns 400 for the same reason — read the booking back with Get Held Booking to see which cabin is held before listing again.

When a cabin cannot be secured. Availability is shared with every other booking, so a cabin listed a moment ago may already have been taken. That returns 409 with the booking unchanged, and the remedy is to list the available numbers again and choose another cabin. Nothing is silently substituted — whenever this call succeeds, cabins[].cabinNumber in the response is the cabin you hold.