Resource Preferences Handling in Direct Assignment
With the 25D update, Resource Preferences (i.e., recommended, forbidden, and required resources) are supported for API calls FindMatchingResources and ShowBookingGrid in direct assignment mode.
This enhancement enables organizations to control how activities are assigned to field resources by defining assignment rules in the request. These preferences influence booking behavior by enforcing which resources should be prioritized, avoided, or strictly required. For example, a company may assign activities to specific resources who already have security clearance or access to restricted areas ('required'), prioritize assigning technicians already familiar to the customer or who have previously serviced the location ('preferred'), or exclude resources who may have a potential conflict of interest with the customer or activity, such as being previously involved in a related audit, legal case, or business negotiation ('forbidden').
showBookingGrid API Operation Changes
A new resourcePreferences array has been added to showBookingGrid API operation with the following structure. The array itself is optional, but if included, it must contain the following mandatory fields:
Table: resourcePreferences Array
| Array | Field | Type | Required | Description | Allowed Values |
|---|---|---|---|---|---|
| resourcePreferences | - | array | Optional | Resource preference rules container. | - |
| resourceID | string | Mandatory | The unique identifier of the resource in Oracle Field Service. | Existing resources External ID values | |
| preferenceType | string | Mandatory | Indicates the type of resource preference for the activity in the booking process.
|
"required", "preferred", "forbidden" |
The following is an example of how the resourcePreferences array should appear in a request:
The description of resourcePreferences node
"resourcePreferences" : [
{
"resourceId":"string",
"preferenceType":"enum"
}
]
In addition to the new resourcePreferences array, the following enhancements have been made:
- The
resourceFieldsrequest array now supports the valueresourcePreference. - The
resourcesDictionaryresponse array now supports new calculated valueresourcePreference, which may return one of the following: "required" or"preferred".
While "forbidden" is a valid resource preference, forbidden resources are never returned as a part of the response.
The following example shows how these changes appear in a typical request and response payload:
Request and response mentioned parts
{
"dateFrom": "2025-04-14",
"dateTo": "2025-04-14",
"includeTimeSlotsDictionary" : true,
"includeResourcesDictionary" : true,
"resourceFields": ["resourceId","resourcePreference"],
"lateStartMitigation": 20,
"identifyActivityBy": "activityId",
"activity":
{
"activityId":8762762,
"resourcePreferences": [
{
"resourceId": "Tech1AreaN",
"preferenceType": "required"
}
]
}
}
{
"duration": 26,
"travelTime": 30,
"workZone": "LONGWOOD",
"timeSlotsDictionary": [...],
"resourcesDictionary": [
{
"resourceId": "Tech1AreaN",
"name": "Tech1AreaN",
"resourcePreference": "required"
}
],
"areas": [
....
]
}
showBookingGrid API Resource Preference Processing
When booking a new activity:
- Required Resources:
- Only resources marked as "required" are considered.
- If no "required" resources are available, the response returns "noCapacity" reason.
- Forbidden Resources:
- Resources marked as "forbidden" are excluded, even if they are the only available options.
- If the exclusion leads to no available resources, the operation returns "noCapacity" reason.
- Preferred Resources:
- The system prioritizes "preferred" resources.
- Non-preferred resources will only be returned if no "preferred" resources are available.
When re-booking an existing activity, the same preferences are applied in the following order:
- Preferences provided in the request take precedence over those defined in the activity
- An empty preference list (
resourcePreferencesarray) in the request clears existing preferences in the activity - Activity-level resources preferences apply only when no
resourcePreferencesarray is included in the request
showBookingGrid API request/response examples
Request / Response example in booking (new activity creation) mode
POST https://frontend.ofsc.team/rest/ofscCapacity/v1/showBookingGrid HTTP/1.1
Accept: application/json
Content-Type: application/json
{
"dateFrom": "2025-04-30",
"dateTo": "2025-04-30",
"returnReasons":"true",
"resourceFields": ["resourceId", "resourcePreference"],
"includeTimeSlotsDictionary" : true,
"includeResourcesDictionary" : true,
"extended":"false",
"testMode":"false",
"lateStartMitigation": 20,
"activity":
{
"resourcePreferences":[
{
"resourceId": "Tech1AreaTF",
"preferenceType": "preferred"
},
{
"resourceId": "Tech1AreaN",
"preferenceType": "required"
}
],
"string_text_activity_property": "IN",
"BookingStatisticProperty_1": "PROP4",
"BookingStatisticProperty_2": "PROP5",
"BookingStatisticProperty_3": "PROP6",
"BookingStatisticProperty_4": "PROP7",
"duration":60,
"activityType":"default_customer_activity_type",
"city": "Merritt Island",
"googleAddress": "301 Grove Blvd, Merritt Island, FL 32953, USA",
"address":"301 Grove Blvd",
"state":"FL",
"country_code":"US",
"postalCode": "32953",
"latitude": 28.3789106,
"longitude": -80.7103838,
"timeZone":"Etc/UTC"
}
}
HTTP/2 200
server: nginx/1.20.1
date: Tue, 29 Apr 2025 17:36:47 GMT
content-type: application/json; charset=utf-8
cache-control: no-store, no-cache
strict-transport-security: max-age=31536000
{
"duration": 60,
"travelTime": 40,
"actualAtTime": "2025-04-29 17:36:47",
"workZone": "ChristmasBKFRD",
"timeSlotsDictionary": [
{
"label": "08-10",
"name": "08-10",
"timeFrom": "08:00:00",
"timeTo": "10:00:00"
},
{
"label": "15-17",
"name": "15-17",
"timeFrom": "15:00:00",
"timeTo": "17:00:00"
},
{
"label": "14-18",
"name": "14-18",
"timeFrom": "14:00:00",
"timeTo": "18:00:00"
},
{
"label": "10-12",
"name": "10-12",
"timeFrom": "10:00:00",
"timeTo": "12:00:00"
}
],
"resourcesDictionary": [
{
"resourceId": "Tech1AreaN",
"name": "Tech1AreaN",
"resourcePreference": "required"
}
],
"areas": [
{
"label": "AreaTF",
"name": "AreaTF",
"bucket": "AreaTF",
"averageBucketTravel": 40,
"averageTravelKeyTravel": 5,
"timeZone": "Etc/UTC",
"areaTimeSlots": [
"08-10",
"15-17",
"14-18",
"10-12"
],
"dates": [
{
"date": "2025-04-30",
"hasNearbyActivities": false,
"hasForecastedActivities": false,
"timeZoneDiff": 0,
"timeSlots": [
{
"label": "10-12",
"resourceId": "Tech1AreaN",
"recommendationInfo": {
"additionalTravel": 13,
"travelKeyMatch": false
},
"setPositionInRoute": {
"position": "first"
}
},
{
"label": "14-18",
"resourceId": "Tech1AreaN",
"recommendationInfo": {
"additionalTravel": 13,
"travelKeyMatch": false
},
"setPositionInRoute": {
"position": "first"
}
},
{
"label": "15-17",
"resourceId": "Tech1AreaN",
"recommendationInfo": {
"additionalTravel": 13,
"travelKeyMatch": false
},
"setPositionInRoute": {
"position": "first"
}
},
{
"label": "08-10",
"resourceId": "Tech1AreaN",
"recommendationInfo": {
"additionalTravel": 13,
"travelKeyMatch": false
},
"setPositionInRoute": {
"position": "first"
}
}
]
}
]
}
]
}
Request / Response example in re-booking mode
POST https://frontend.ofsc.team/rest/ofscCapacity/v1/showBookingGrid HTTP/1.1
Accept: application/json
Content-Type: application/json
{
"dateFrom": "2025-05-30",
"dateTo": "2025-05-30",
"includeTimeSlotsDictionary" : true,
"includeResourcesDictionary" : true,
"returnReasons":"true",
"resourceFields": ["resourceId","resourcePreference"],
"extended":"false",
"testMode":"false",
"lateStartMitigation": 20,
"identifyActivityBy": "activityId",
"activity":
{
"activityId":8762784,
"resourcePreferences": [
{
"resourceId": "Tech1AreaN",
"preferenceType": "preferred"
}
]
}
}
HTTP/2 200
server: nginx/1.20.1
date: Tue, 29 Apr 2025 17:37:25 GMT
content-type: application/json; charset=utf-8
cache-control: no-store, no-cache
strict-transport-security: max-age=31536000
{
"duration": 60,
"travelTime": 40,
"actualAtTime": "2025-04-29 17:37:24",
"workZone": "ChristmasBKFRD",
"timeSlotsDictionary": [
{
"label": "08-10",
"name": "08-10",
"timeFrom": "08:00:00",
"timeTo": "10:00:00"
},
{
"label": "15-17",
"name": "15-17",
"timeFrom": "15:00:00",
"timeTo": "17:00:00"
},
{
"label": "14-18",
"name": "14-18",
"timeFrom": "14:00:00",
"timeTo": "18:00:00"
},
{
"label": "10-12",
"name": "10-12",
"timeFrom": "10:00:00",
"timeTo": "12:00:00"
}
],
"resourcesDictionary": [
{
"resourceId": "Tech1AreaN",
"name": "Tech1AreaN",
"resourcePreference": "preferred"
}
],
"areas": [
{
"label": "AreaTF",
"name": "AreaTF",
"bucket": "AreaTF",
"averageBucketTravel": 40,
"averageTravelKeyTravel": 5,
"timeZone": "Etc/UTC",
"areaTimeSlots": [
"08-10",
"15-17",
"14-18",
"10-12"
],
"dates": [
{
"date": "2025-05-30",
"hasNearbyActivities": false,
"hasForecastedActivities": false,
"timeZoneDiff": 0,
"timeSlots": [
{
"label": "10-12",
"resourceId": "Tech1AreaN",
"recommendationInfo": {
"additionalTravel": 13,
"travelKeyMatch": false
},
"setPositionInRoute": {
"position": "first"
}
},
{
"label": "14-18",
"resourceId": "Tech1AreaN",
"recommendationInfo": {
"additionalTravel": 13,
"travelKeyMatch": false
},
"setPositionInRoute": {
"position": "first"
}
},
{
"label": "15-17",
"resourceId": "Tech1AreaN",
"recommendationInfo": {
"additionalTravel": 13,
"travelKeyMatch": false
},
"setPositionInRoute": {
"position": "first"
}
},
{
"label": "08-10",
"resourceId": "Tech1AreaN",
"recommendationInfo": {
"additionalTravel": 13,
"travelKeyMatch": false
},
"setPositionInRoute": {
"position": "first"
}
}
]
}
]
}
]
}
findMatchingResources API Operation Changes
The following enhancements have been implemented to improve flexibility and support resource preference handling during booking and rebooking:
- Already existing
resourcePreferencesrequest array is now supported in re-booking mode as well - The resource response object now supports new calculated value
resourcePreferenceas part of its default fields. This field may return one of the following values: "required" or "preferred".
Note While "forbidden" is possible as a resource preference, forbidden resources are never returned as a part of the result.
findMatchingResources API Resource Preference Processing
When booking a new activity:
- Required Resources:
- Only resources marked as "required" are considered.
- If no "required" resources are available, no resources are returned.
- Forbidden Resources:
- Any resources marked as "forbidden" are excluded from the response, even if they are the only available options.
- If the exclusion leads to no available resources, no resources are returned.
- Preferred Resources:
- The system prioritizes "preferred" resources when suggesting resources in the response.
When re-booking an existing activity, the same preferences are applied in the following order:
- Preferences provided in the request take precedence over those defined in the activity
- An empty preference list (
resourcePreferencesarray) in the request clears existing preferences in the activity - Activity-level resources preferences apply only when no
resourcePreferencesarray is included in the request
findMatchingResources API request/response examples
Request / Response example in booking (new activity creation) mode
POST https://frontend.ofsc.team/rest/ofscCore/v1/resources/custom-actions/findMatchingResources HTTP/1.1
Accept: application/json
Content-Type: application/json
{
"criteria": {
"finalTravelSupport": false,
"resourcePreference": 0.0,
"workSkill": 100,
"workTime": 10,
"workZone": 100,
"includeResources": "technicians"
},
"limit": 4,
"fields": [
"resourceId",
"resourceType",
"parentResourceId"
],
"forecastDuringBooking": {
"useForecastDuringBooking": false,
"optimizationGoal": "minimizeAdditionalTravel",
"minForecastRangeDay": 1,
"maxForecastRangeDay": 10,
"explainRemovedOptions": true
},
"schedulesToReturn": [
"2025-06-14"
],
"schedulesFields": [
"forecastDuringBookingDetails",
"fitness",
"arrivalTimeOptions",
"routeDetails",
"freeTimeWindows"
],
"activity": {
"resourcePreferences":[
{
"resourceId": "Tech1AreaTF",
"preferenceType": "required"
},
{
"resourceId": "Tech2AreaN",
"preferenceType": "preferred"
},
{
"resourceId": "Tech2AreaN",
"preferenceType": "preferred"
},
{
"resourceId": "Tech3AreaN",
"preferenceType": "forbidden"
}
],
"string_text_activity_property": "IN",
"BookingStatisticProperty_1": "PROP4",
"BookingStatisticProperty_2": "PROP5",
"BookingStatisticProperty_3": "PROP6",
"BookingStatisticProperty_4": "PROP7",
"StringTextActivity": "IN",
"activityType": "default_customer_activity_type",
"timeZone": "(UTC+02:00) Athens - Eastern European Time (EET)",
"customerName": "fmr customer name",
"city": "Merritt Island",
"googleAddress": "301 Grove Blvd, Merritt Island, FL 32953, USA",
"address":"301 Grove Blvd",
"state":"FL",
"country_code":"US",
"postalCode": "32953",
"latitude": 28.3789106,
"longitude": -80.7103838,
"WO_TYPE": "4",
"duration":60
}
}
HTTP/2 200
server: nginx/1.20.1
date: Wed, 04 Jun 2025 13:12:36 GMT
content-type: application/json; charset=utf-8
cache-control: no-store, no-cache
strict-transport-security: max-age=31536000
{
"totalResults": 1,
"limit": 4,
"offset": 0,
"actualAtTime": "2025-06-04 13:12:36",
"items": [
{
"resource": {
"resourceId": "Tech1AreaTF",
"status": "active",
"language": "en",
"languageISO": "en-US",
"resourceType": "field_resourcer_full",
"parentResourceId": "AreaTF",
"resourcePreference": "required"
},
"schedules": {
"2025-06-14": {
"fitness": {
"workTime": 600,
"workSkill": 100,
"workZone": 100,
"resourcePreference": 0.5
},
"freeTimeWindows": [
[
"08:00",
"18:00"
]
],
"arrivalTimeOptions": [
{
"minStartTime": "11:38",
"maxStartTime": "17:00",
"workZoneMatch": false,
"setPositionInRoute": {
"position": "first"
},
"additionalTravel": 76
}
]
}
}
}
]
}
Request / Response example in re-booking mode
POST https://frontend.ofsc.team/rest/ofscCore/v1/resources/custom-actions/findMatchingResources HTTP/1.1
Accept: application/json
Content-Type: application/json
{
"criteria": {
"resourcePreference": 0.0,
"workSkill": 100,
"workTime": 10,
"workZone": 100,
"includeResources": "technicians"
},
"limit": 4,
"fields": [
"resourceId",
"resourceType",
"parentResourceId"
],
"schedulesToReturn": [
"2025-06-14"
],
"schedulesFields": [
"forecastDuringBookingDetails",
"fitness",
"arrivalTimeOptions",
"routeDetails",
"freeTimeWindows"
],
"activityId":8762789,
"activity": {
"resourcePreferences":[
{
"resourceId": "Tech1AreaTF",
"preferenceType": "required"
},
{
"resourceId": "Tech1AreaN",
"preferenceType": "preferred"
},
{
"resourceId": "Tech2AreaN",
"preferenceType": "preferred"
},
{
"resourceId": "Tech3AreaN",
"preferenceType": "forbidden"
}
]
}
}
HTTP/2 200
server: nginx/1.20.1
date: Thu, 05 Jun 2025 07:13:15 GMT
content-type: application/json; charset=utf-8
cache-control: no-store, no-cache
strict-transport-security: max-age=31536000
{
"totalResults": 1,
"limit": 4,
"offset": 0,
"actualAtTime": "2025-06-05 07:13:15",
"items": [
{
"resource": {
"resourceId": "Tech1AreaTF",
"status": "active",
"language": "en",
"languageISO": "en-US",
"resourceType": "field_resourcer_full",
"parentResourceId": "AreaTF",
"resourcePreference": "required"
},
"schedules": {
"2025-06-14": {
"fitness": {
"workTime": 120,
"workSkill": 100,
"workZone": 100,
"resourcePreference": 0.5
},
"freeTimeWindows": [
[
"08:00",
"18:00"
]
],
"arrivalTimeOptions": [
{
"minStartTime": "15:00",
"maxStartTime": "17:00",
"workZoneMatch": false,
"setPositionInRoute": {
"position": "first"
},
"additionalTravel": 20
}
]
}
}
}
]
}
- Provides the ability to assign activities to designated resources early in the process, making it easier to accommodate specific business needs, compliance standards, or operational constraints.
- Enhances efficiency by reducing the need for manual intervention and back-and-forth in the scheduling process.
Steps to Enable
This feature is enabled automatically starting from version 25D. It will work for every call to FindMatchingResources or ShowBookingGrid if the request includes resource preferences or the activity being rebooked has preferences set.
Tips And Considerations
To rebook activities while ignoring the existing resource preferences, set the resourcePreferences array in the request to an empty. Note that the resource preferences in the request override those in the activity. Consider updating the activity resource preferences afterward if changes must persist.