6 Update Room and Rate Grid
Business Context
A block is an allocation of rooms for multiple room types, reserved for a specific date period, that does not require you to create individually named reservations. Blocks are used to reserve multiple rooms for events, such as weddings or conferences, inbound tour groups or airline crews, or for long-term allocations, such as airline allotments. To allocate guest rooms for a group of travellers, a block header must exist (for more information, refer to Create a Block with or without Room Grid). In this document, you can follow the steps to load a block room allocation using REST APIs. There are different operations available to use: two synchnronous and two asynchronous. It is recommended to use the asynchronous calls for longer blocks (that is, greater than 30 days).
Prerequisites
Table 6-1 Required Software Tools
Tool | Description | Links |
---|---|---|
Postman |
Postman is an API Platform that allows you to design, create and test API's. Use Postman to send API requests or to use the Postman collections provided. |
Table 6-2 Current Versions Required
OPERA Cloud Platform Module | Description | Minimum Version |
---|---|---|
OPERA Cloud Services |
The customer must have a subscription to OPERA Cloud Foundation |
|
Oracle Hospitality Integration Platform (OHIP) |
For customers, OHIP is included in the subscription to OPERA Cloud Foundation. Partners need a subscription to the Oracle Hospitality Integration Cloud Service. |
Configuration of OPERA Controls
To activate the Create Block functionality, you must ensure the following OPERA Controls are active in the target property. You can use the following API operations to validate the settings:
Ensure that application function BLOCKS - BUSINESS BLOCK is active
RQ: ent/config/v1/settings?hotelId={{HotelId}}¶meterNameWildCard=BUSINESS BLOCK
Check if the site is using OCCUPANCY SPLIT BY ROOM TYPE
RQ: ent/config/v1/settings?hotelId={{HotelId}}¶meterNameWildCard=OCCUPANCY SPLIT PER ROOM TYPE
Check if the site is using RATE CODE MANDATORY BLOCK HEADER
RQ: ent/config/v1/settings?hotelId={{HotelId}}¶meterNameWildCard=RATE CODE MANDATORY BLOCK HEADER
Critera dependencies:
Block Status
RQ: blk/config/v1/blockStatusCodes
Rate Code (if mandatory)
RQ: rtp/v1/ratePlans?includeRateInformation=false&includeInactive=true&offset=1&limit=200&sellDate=2024-02-08&hotelId={{hotelId}}
Room Types
RQ: rm/config/v1/hotels/{{hotelId}}/roomTypes?accessible=false&includeInactive=false&offset=1&hotelIds={{hoteldId}}&summaryInfo=true&limit=25&physical=true&pseudo=false
Workflow
Step by step solution including:
Figure 6-1 The sequence of API calls (in any direction)

Description of Steps
A typical process to update the room and rate grid is as follows:
- Ensure that the block header you are trying to add Room and Rate grid exists using the getBlock RQ.
- Add the room block using putBlockAllocation, putBlockAllocationRange, postBlockAllocation
(async), or postBlockAllocationRange (async).
- When the OCCUPANCY PER ROOM TYPE OPERA control is not active, only submit inventory updates for the onePerson element. When the OPERA Control is active, inventory updates can be done for onePerson, twoPerson, threePerson, and FourPerson. Rates can be submitted for all occupancy levels, regardless of the OPERA Control setting.
- When the block is not in an open-for-pickup status, meaning reservations cannot be made against the block, the allocation element must carry the value INITIAL.
- When the block is open for pickup, any inventory updates must be done for allocation = ACTUAL.
- If a valid rate code has been submitted as part of the block creation process, it is not necessary to send rate amounts during the grid update process. Rate amounts in OPERA are populated automatically from the rate code on the block header.
- Description of differences between the four different RQs.
- putBlockAllocation
- Contains one element per Date per Room Type (but elements can be repeated within the same call to loop through).
- Start and End Date for each collection need to be the same
- Recommended for shorter date ranges ( < 30 nights) where the inventory or rate values vary between different dates / room types.
- putBlockAllocationRange
- Contains one collection that applies the same inventory and rate values to a date range and list of room types.
- Start and End Date for each collection define the date range.
- Recommended for shorter date ranges ( < 30 nights) where the inventory and rate values are the same for all dates and room types within the range / collection.
- Only one range can be contained within one call
- postBlockAllocation (async)
Note:
Only available from OPERA Cloud version 23.4 onwards.
- Contains one element per Date per Room Type (but elements can be repeated within the same call to loop through).
- Start and End Date for each collection must be the same.
- Recommended for longer date ranges ( > 30 nights) where the inventory or rate values vary between different dates / room types.
- postBlockAllocationRange (async)
Note:
Only available from OPERA Cloud version 23.5 onwards.
- Can contain multiple collections where each collection applies the same inventory and rate values to the date range and list of room types for that collection.
- Start and End Date for each collection define the date range.
- Recommended for longer date ranges ( > 30 nights) where the inventory and rate values are the same for multiple dates and room types within the range / collection.
- Multiple ranges can be posted within one call in a loop.
- putBlockAllocation
- Retrieve the udpated Block using getBlock with fetchInstructions for the room grid to ensure that the block was updated with the correct attributes (optional).
Sample calls: Sample API calls for steps described in the diagram.
Sample for getBlock
Fetch Block with Grid Details
GET{{HostName}}/blk/v1/hotels/{{HotelId}}/blocks/{{BlockId}}?fetchAllocatedRoomTypes=true&markAsRecentlyAccessed=false&roomTypes=DLXQ&roomTypes=STDK&roomTypes=STDQ&roomAllocationCriteria=Initial&fetchInstructions=RateGrid&numberOfDays=2&startDate=2024-09-06&roomAllocationCriteria=CutoffDate
200 Response: OK
{
"blocks": {
"blockInfo": [
{
"block": {
"blockIdList": [
{
"id": "{{BLockId}}",
"type": "Block",
"idContext": "OPERA"
}
],
"roomAllocations": {
"roomAllocationType": [
{
"roomAllocationInfo": [
{
"roomGridInvSummary": [
{}
],
"availableRoomGridInvSummary": [
{}
],
"stayDate": "2024-09-06",
"extendedStay": false
},
{
"roomGridInvSummary": [
{}
],
"availableRoomGridInvSummary": [
{}
],
"stayDate": "2022-05-19",
"extendedStay": false
},
{
"roomGridInvSummary": [
{}
],
"availableRoomGridInvSummary": [
{}
],
"stayDate": "2022-05-20",
"extendedStay": false
},
{
"roomGridInvSummary": [
{}
],
"availableRoomGridInvSummary": [
{}
],
"stayDate": "2022-05-21",
"extendedStay": false
},
{
"roomGridInvSummary": [
{}
],
"availableRoomGridInvSummary": [
{}
],
"stayDate": "2022-05-22",
"extendedStay": false
},
{
"roomGridInvSummary": [
{}
],
"availableRoomGridInvSummary": [
{}
],
"stayDate": "2022-05-23",
"extendedStay": false
},
{
"roomGridInvSummary": [
{}
],
"availableRoomGridInvSummary": [
{}
],
"stayDate": "2022-05-24",
"extendedStay": false
}
],
"allocation": "Initial"
},
{
"roomAllocationInfo": [
{
"roomGridInvSummary": [
{
"onePerson": 0,
"twoPerson": 0,
"threePerson": 0,
"fourPerson": 0
}
],
"availableRoomGridInvSummary": [
{}
],
"stayDate": "2022-05-18",
"extendedStay": false
},
{
"roomGridInvSummary": [
{
"onePerson": 0,
"twoPerson": 0,
"threePerson": 0,
"fourPerson": 0
}
],
"availableRoomGridInvSummary": [
{}
],
"stayDate": "2022-05-19",
"extendedStay": false
},
{
"roomGridInvSummary": [
{
"onePerson": 0,
"twoPerson": 0,
"threePerson": 0,
"fourPerson": 0
}
],
"availableRoomGridInvSummary": [
{}
],
"stayDate": "2022-05-20",
"extendedStay": false
},
{
"roomGridInvSummary": [
{
"onePerson": 0,
"twoPerson": 0,
"threePerson": 0,
"fourPerson": 0
}
],
"availableRoomGridInvSummary": [
{}
],
"stayDate": "2022-05-21",
"extendedStay": false
},
{
"roomGridInvSummary": [
{
"onePerson": 0,
"twoPerson": 0,
"threePerson": 0,
"fourPerson": 0
}
],
"availableRoomGridInvSummary": [
{}
],
"stayDate": "2022-05-22",
"extendedStay": false
},
{
"roomGridInvSummary": [
{
"onePerson": 0,
"twoPerson": 0,
"threePerson": 0,
"fourPerson": 0
}
],
"availableRoomGridInvSummary": [
{}
],
"stayDate": "2022-05-23",
"extendedStay": false
},
{
"roomGridInvSummary": [
{
"onePerson": 0,
"twoPerson": 0,
"threePerson": 0,
"fourPerson": 0
}
],
"availableRoomGridInvSummary": [
{}
],
"stayDate": "2022-05-24",
"extendedStay": false
}
],
"allocation": "CutoffDate"
}
],
"masterInfo": {
"roomTypes": []
},
"startDate": "2022-05-18",
"numberOfDays": 7
},
"hotelId": "BHOTEL",
"markAsRecentlyAccessed": false
}
}
]
},
"links": []
}
Sample for putBlockAllocation
Note:
Although there is a start and end date for each grid cell, in this call, the start and end date in each collection must be the same (and the collection must be repeated for any additional dates).
This call is for a block that is not open for pickup. Please note the element: "allocation": "INITIAL". When running this RQ for an open-for-pickup call, the elements must be :"allocation": "ACTUAL."
Create / Update Room Grid (Cell by Cell)
PUT{{HostName}}/blk/v1/hotels/{{HotelId}}/blocks/{{BlockId}}/allocation
Body:
{
"criteria": {
"hotelId": "{{HotelId}}",
"blockId": {
"type": "Block",
"idContext": "OPERA",
"id": "{{BlockId}}"
},
"allocationRoomTypes": [
{
"allocationGridDates": [
{
"roomAllocationInfo": [
{
"inventory": {
"forceOverbook": false
},
"rate": {
"onePerson": "240",
"twoPerson": "240",
"threePerson": "260"
},
"start": "2023-12-01",
"end": "2023-12-01"
},
{
"inventory": {
"forceOverbook": false
},
"rate": {
"onePerson": "200",
"twoPerson": "220"
},
"start": "2023-12-02",
"end": "2023-12-02"
}
],
"allocation": "RATES"
},
{
"roomAllocationInfo": [
{
"inventory": {
"forceOverbook": false,
"onePerson": "4",
"twoPerson": "4"
},
"rate": {},
"start": "2023-12-01",
"end": "2023-12-01"
},
{
"inventory": {
"forceOverbook": false,
"onePerson": "3",
"twoPerson": "3"
},
"rate": {},
"start": "2023-12-02",
"end": "2023-12-02"
}
],
"allocation": "INITIAL"
}
],
"roomType": "EXEC"
}
],
"genericRoomType": false
}
}
200 Response: OK
Sample for putBlockAllocationRange
Note:
The start and end date in the collection define the date range for which the given values should be populated. Only one range can be defined per call.
This call is for a block that is open for pickup. Please note the element: "allocation": "Actual". When running this RQ for a not open-for-pickup call, the elements must be :"allocation": "Initial"
Create / Update Room Grid (Range)
PUT{{HostName}}/blk/v1/hotels/{{HotelId}}/blocks/{{BlockId}}/allocationRange
Body:
{
"blockAllocationRange": {
"blockId": {
"type": "Block",
"idContext": "OPERA",
"id": "{{BlockId}}"
},
"hotelId": "{{HotelId}} ",
"roomTypes": [
"DLXQ"
],
"beginDate": "2023-12-01",
"endDate": "2023-12-02",
"allocationType": "Actual",
"incrementFlag": false,
"blockInventory": {
"onePerson": "8",
"twoPerson": "3"
},
"blockRates": {
"onePerson": "240",
"twoPerson": "280"
},
"includedDays": "1111111",
"rangeMode": "Core",
"genericRoomType": false
}
}
200 Response: OK
Sample for postBlockAllocation (async)
Note:
Even though there is a start and end date for each grid cell, in this call the start and end date in each collection must be the same (and the collection must be repeated for any additional dates)
This call is for a block that is not open for pickup. Please note the element: "allocation": "INITIAL". When running this RQ for an open-for-pickup call, the elements must be :"allocation": "ACTUAL"
Post Block Allocation cell-by-cell (async)
POST{{HostName}}/blk/async/v1/hotels/{{HotelId}}/blocks/{{BlockId}}/allocation
Body:
{
"criteria": {
"hotelId": "{{HotelId}}",
"blockId": {
"type": "Block",
"idContext": "OPERA",
"id": "{{BlockId}}"
},
"allocationRoomTypes": [
{
"allocationGridDates": [
{
"roomAllocationInfo": [
{
"inventory": {
"forceOverbook": false
},
"rate": {
"onePerson": "240",
"twoPerson": "240",
"threePerson": "260"
},
"start": "2023-12-01",
"end": "2023-12-01"
},
{
"inventory": {
"forceOverbook": false
},
"rate": {
"onePerson": "200",
"twoPerson": "220"
},
"start": "2023-12-02",
"end": "2023-12-02"
}
],
"allocation": "RATES"
},
{
"roomAllocationInfo": [
{
"inventory": {
"forceOverbook": false,
"onePerson": "4",
"twoPerson": "4"
},
"rate": {},
"start": "2023-12-01",
"end": "2023-12-01"
},
{
"inventory": {
"forceOverbook": false,
"onePerson": "3",
"twoPerson": "3"
},
"rate": {},
"start": "2023-12-02",
"end": "2023-12-02"
}
],
"allocation": "INITIAL"
}
],
"roomType": "EXEC"
}
],
"genericRoomType": false
}
}
202 Response: Accepted
Retrieve Process ID from RS Headers - Location and append it into the next calls URL
HEAD{{HostName}}/blk/async/v1/hotels/{{HotelId}}/blocks/{{BlockId}}/allocation/1134ad3c-95fa-d7d8-e063-666a040a111d
201 Response: Created
Retrieve Process ID from RS Headers - Location and append it into the next calls URL
GET{{HostName}}/blk/async/v1/hotels/{{HotelId}}/blocks/{{BlockId}}/allocation/1134accb-f697-56b0-e063-666a040ae3b4
200 Response: OK
Body:
{
"status": "Success"
}
Sample for postBlockAllocationRanges (async)
Note:
Although there is a start and end date for each grid cell, in this call, the start and end date in each collection must be the same (and the collection must be repeated for any additional dates).
This call is for a block that is not open for pickup. Note the element: "allocation": "INITIAL." When running this RQ for an open-for-pickup call, the elements must be :"allocation": "ACTUAL."
Post Block Allocation Ranges (async)
POST{{HostName}}/blk/async/v1/hotels/{{HotelId}}/blocks/{{BlockId}}/allocationRanges
Body:
{
"blockAllocationRange": {
"blockId": {
"type": "Block",
"idContext": "OPERA",
"id": "{{BlockId}}"
},
"hotelId": "{{HotelId}} ",
"roomTypes": [
"DLXQ"
],
"beginDate": "2023-12-01",
"endDate": "2023-12-02",
"allocationType": "Actual",
"incrementFlag": false,
"blockInventory": {
"onePerson": "8",
"twoPerson": "3"
},
"blockRates": {
"onePerson": "240",
"twoPerson": "280"
},
"includedDays": "1111111",
"rangeMode": "Core",
"genericRoomType": false
}
}
202 Response: Accepted
Retrieve Process ID from RS Headers - Location and append it into the next calls URL
HEAD{{HostName}}/blk/async/v1/hotels/{{HotelId}}/blocks/{{BlockId}}/allocationRanges/1134ad3c-95fa-d7d8-e063-666a040a111d
201 Response: Created
Retrieve Process ID from RS Headers - Location and append it into the next calls URL
GET{{HostName}}/blk/async/v1/hotels/{{HotelId}}/blocks/{{BlockId}}/allocationRanges/1134accb-f697-56b0-e063-666a040ae3b4
200 Response: OK
Body:
{
"status": "Success"
}
References
-
For more information, review the Anti-Patterns chapter in the OHIP user guide to learn more about functional and technical anti-patterns.
-
Fore more information, refer to the Blocks introduction topic in the OPERA Cloud Services user guide.