Skip to content

SAP/fsm-sdk

SAP Field Service Management SDK

npm version integration test REUSE status badge


JavaScript SDK to Interface with SAP Field Service Management APIs and Services.

Find more documentation and related information at SAP Field Service Management Documentation

Getting started

install from NPM

npm i fsm-sdk --save

using 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:

Examples

Some illustrative cases are provided in the examples folder.


CoreAPIClient

The CoreAPIClient API actions will return a Promise and is asynchronous by default.

Authentication & Token Management

// 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');

Account API

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);

Service Management API

The Service Management API provides access to activities, service calls, and composite operations.

Activity Business Actions

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
});

Activity Bulk Business Actions

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'
  }
]);

Service Call Business Actions

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');

Composite Operations

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 });

Translation API

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');

Rules API

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'
});

Legacy Data Cloud API (Deprecated)

⚠️ Note: The Data Service API (Data Cloud) is deprecated. For service calls and activities, use the Service Management API instead.

Query for objects using CoreSQL

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']);

CRUD object

related doc's:

Create a new object

const serviceCall = {
   id: fsm.CoreAPIClient.createUUID(), // => 36A5626F65A54FE7911F536C501D151A
   ...
};

await client.post('ServiceCall', serviceCall);

Read object by id or externalId

await client.getById('ServiceCall', '36A5626F65A54FE7911F536C501D151A');
// or
await client.getByExternalId('ServiceCall', 'my-1');

Update object (providing full new version)

await client.put('ServiceCall', { ... });
// or
await client.putByExternalId('ServiceCall', { ... });

Update object (providing only fields to change)

await client.patch('ServiceCall', {
    id: '36A5626F65A54FE7911F536C501D151A',
    subject: 'update-only-subject',
    lastChanged: 1535712340
  });
// or
await client.patchByExternalId('ServiceCall', { externalId: 'my-1', ... });

Delete object by id or externalId

await client.deleteById('ServiceCall', {
    id: '36A5626F65A54FE7911F536C501D151A',
    lastChanged: 1535712340
  });
// or
await client.deleteByExternalId('ServiceCall', { externalId: 'my-1', ... });
lastChanged

The lastChanged field is used for optimistic locking. It's like a version-key you must provide in order to update an object.

Batch Actions (Transactions)

// 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);

Support

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".

License

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.

About

A client library that provides APIs to call Services/APIs from SAP Field Service Management (aka CoreSystems).

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 6