Find more documentation and related information at SAP Field Service Management Documentation
- SAP Field Service Management SDK
install from NPM
npm i fsm-sdk --saveusing the sdk in NodeJS with credentials:
const fsm = require('fsm-sdk');
const client = new fsm.CoreAPIClient({
// [mandatory] your client configuration
clientIdentifier: '<your-clientIdentifier>',
clientSecret: '<your-clientSecret>',
clientVersion: '<your-clientVersion>',
// [optional] oauth grant type, default=password
authGrantType: 'password' | 'client_credentials' | undefined
// [optional] | [mandatory] if oauth grant type password
authAccountName: '<your-authAccountName>',
// [optional] | [mandatory] if oauth grant type password
authUserName: '<your-authUserName>',
// [optional] | [mandatory] if oauth grant type password
authPassword: '<your-authPassword>',
// [optional] or default=FIRST
authCompany: '<your-authCompany>',
// [optional] provide verbose logs
debug: false,
// [optional] enable using custom oauth endpoints
oauthEndpoint: 'https://eu.fsm.cloud.sap/api/oauth2/v2',
// [optional] client will cache token (helpful for writing integration tests)
tokenCacheFilePath: './.myToken.json'
});related doc's:
- Field Service Management - Integration Guidelines
- Access API (OAuth 2.0)
- Generating Client ID and Secret
Some illustrative cases are provided in the examples folder.
The CoreAPIClient API actions will return a Promise and is asynchronous by default.
// Login explicitly (optional - auto-login happens on first API call)
await client.login();
// Get current OAuth token
const token = client.getToken();
// Set OAuth token manually
client.setToken(token);
// Set authentication company (for multi-company tokens)
client.setAuthCompany('COMPANY_NAME');Access account and company information:
// Get all accessible accounts
const accounts = await client.accountAPI.getAccounts();
// Get companies by account ID
const companies = await client.accountAPI.getCompaniesByAccount(accountId);The Service Management API provides access to activities, service calls, and composite operations.
Perform business actions on individual activities:
// Cancel an activity
await client.serviceManagementAPI.activity.cancel('activity-id', {
cancelServiceCallConfirmed: true,
cancellationReason: 'Customer request'
});
// Close an activity
await client.serviceManagementAPI.activity.close('activity-id', {
udfValues: [{ name: 'customField', value: 'completed' }]
});
// Duplicate an activity
await client.serviceManagementAPI.activity.duplicate('activity-id', {
crew: 'crew-id',
responsibles: ['tech-1', 'tech-2'],
startDateTime: '2025-01-15T09:00:00Z'
});
// Plan an activity
await client.serviceManagementAPI.activity.plan('activity-id', {
technician: { id: 'technician-id' },
startDateTime: '2025-01-15T09:00:00Z',
plannedDurationInMinutes: 120,
travelTimeFromInMinutes: 15,
travelTimeToInMinutes: 15
});
// Release an activity
await client.serviceManagementAPI.activity.release('activity-id', {
udfValues: []
});
// Replan an activity
await client.serviceManagementAPI.activity.replan('activity-id', {
technician: { id: 'technician-id' },
startDateTime: '2025-01-16T09:00:00Z',
plannedDurationInMinutes: 90
});
// Reschedule an activity
await client.serviceManagementAPI.activity.reschedule('activity-id', {
technician: { id: 'technician-id' },
startDateTime: '2025-01-17T09:00:00Z',
plannedDurationInMinutes: 120
});Perform business actions on multiple activities at once:
// Cancel multiple activities in bulk
await client.serviceManagementAPI.activity.bulk.cancel([
{ id: 'activity-1', cancellationReason: 'Weather conditions' },
{ id: 'activity-2', cancellationReason: 'Customer cancellation' }
]);
// Plan multiple activities in bulk
await client.serviceManagementAPI.activity.bulk.plan([
{
id: 'activity-1',
technician: { id: 'tech-1' },
startDateTime: '2025-01-15T09:00:00Z',
plannedDurationInMinutes: 90
},
{
id: 'activity-2',
technician: { id: 'tech-2' },
startDateTime: '2025-01-15T11:00:00Z',
plannedDurationInMinutes: 120
}
]);
// Duplicate multiple activities in bulk
await client.serviceManagementAPI.activity.bulk.duplicate([
{
id: 'activity-1',
startDateTime: '2025-01-20T09:00:00Z',
crew: 'crew-id'
}
]);Perform business actions on service calls:
// Cancel a service call
await client.serviceManagementAPI.serviceCall.cancel('service-call-id', {
cancellationReason: 'Customer request'
});
// Mark service call as technically complete
await client.serviceManagementAPI.serviceCall.technicallyComplete('service-call-id');Work with service calls and their nested activities:
// Create service call with activities (tree structure)
const serviceCall = await client.serviceManagementAPI.composite.tree.postServiceCall({
subject: 'Installation Service',
businessPartner: { id: 'bp-id' },
activities: [{
subject: 'Installation',
type: 'INSTALL'
}]
}, { autoCreateActivity: true });
// Get service call with nested structure
const serviceCallTree = await client.serviceManagementAPI.composite.tree.getServiceCall('service-call-id');
// Bulk create service calls
const bulkResult = await client.serviceManagementAPI.composite.bulk.postServiceCalls([
{ subject: 'Service 1', businessPartner: { id: 'bp-id' } },
{ subject: 'Service 2', businessPartner: { id: 'bp-id' } }
], { autoCreateActivity: true });Access translation labels and values:
// Get translation labels
const labels = await client.translationAPI.getLabels();
// Get translation values
const values = await client.translationAPI.getValues('label-id');Manage business rules, monitor execution, and track rule health:
// Get all rules with filtering and pagination
const rulesPage = await client.rulesAPI.getRules({
page: 0,
size: 10,
});
// Get a specific rule by ID
const rule = await client.rulesAPI.getRule('rule-id');
// Create a new rule
const newRule = await client.rulesAPI.createRule({
// <RuleDTO>
});
// Update an existing rule (partial update)
const updatedRule = await client.rulesAPI.updateRule('rule-id', {
enabled: false,
description: 'Updated description'
});
// Create or replace a rule
const upsertedRule = await client.rulesAPI.createOrUpdateRule('rule-id', {
// <RuleDTO>
});
// Get execution records for a rule
const executionRecords = await client.rulesAPI.getRuleExecutionRecords('rule-id', {
page: 0,
size: 20,
status: 'FAILED',
executionDateFrom: '2025-01-01',
executionDateTo: '2025-12-31'
});
⚠️ Note: The Data Service API (Data Cloud) is deprecated. For service calls and activities, use the Service Management API instead.
Provides the [coreSQL] and the [dtos] used in the query see Field Service Management - Query API
const coreSQL =
`SELECT
sc.id,
sc.subject
FROM
ServiceCall sc
WHERE
sc.id = '36A5626F65A54FE7911F536C501D151A'
`;
await client.dataServiceAPI.query(coreSQL, ['ServiceCall']);related doc's:
const serviceCall = {
id: fsm.CoreAPIClient.createUUID(), // => 36A5626F65A54FE7911F536C501D151A
...
};
await client.post('ServiceCall', serviceCall);await client.getById('ServiceCall', '36A5626F65A54FE7911F536C501D151A');
// or
await client.getByExternalId('ServiceCall', 'my-1');await client.put('ServiceCall', { ... });
// or
await client.putByExternalId('ServiceCall', { ... });await client.patch('ServiceCall', {
id: '36A5626F65A54FE7911F536C501D151A',
subject: 'update-only-subject',
lastChanged: 1535712340
});
// or
await client.patchByExternalId('ServiceCall', { externalId: 'my-1', ... });await client.deleteById('ServiceCall', {
id: '36A5626F65A54FE7911F536C501D151A',
lastChanged: 1535712340
});
// or
await client.deleteByExternalId('ServiceCall', { externalId: 'my-1', ... });The lastChanged field is used for optimistic locking.
It's like a version-key you must provide in order to update an object.
// actions will be executed in sequence order like in array
const actions = [
new CreateAction('ServiceCall', { ... }),
new UpdateAction('BusinessPartner', { id, lastChanged ... }), // required for update
new DeleteAction('Address', { id, lastChanged ... }) // required for delete
];
const response = await client.batch(actions)
// response => [ { body: { statusCode: 200|201|400, data: { ... } } }, req1, req2 ]
// data will contain a list resp, unwrap to access first
const [[{ serviceCall }], [{ businessPartner }], ] = response.map(it => it.body.data);In case you need further help, check out the SAP Field Service Management Help Portal or report and incident in SAP Support Portal with the component "CEC-SRV-FSM".
Copyright (c) 2020 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file.