Stitchflow
SAP Sales Cloud logo

SAP Sales Cloud User Management API Guide

API workflow

How to automate user lifecycle operations through APIs with caveats that matter in production.

UpdatedMar 16, 2026

Summary and recommendation

SAP Sales Cloud exposes user management through an OData v2 API at https://<tenant>.crm.ondemand.com/sap/c4c/odata/v1/c4codataapi.

The primary entity for user operations is EmployeeCollection.

Auth is OAuth 2.0 (SAML Bearer Assertion for delegated flows;

client credentials for machine-to-machine);

Basic Auth is deprecated for production.

All write operations - POST, PATCH - require a valid X-CSRF-Token fetched from a prior GET;

stale or missing tokens return HTTP 403.

The API is OData v2: response bodies are wrapped in {"d": {"results": [...]}} not top-level arrays.

Pagination uses $skip / $top with a default and maximum page size of 1000.

Rate limits are not publicly documented;

SAP recommends $batch to reduce call volume in bulk provisioning scenarios.

SCIM 2.0 provisioning is available but is never a direct endpoint on the tenant

it is always mediated through SAP Identity Provisioning Service (IPS), requires Enterprise tier, and must be enabled via SAP support ticket with SAML SSO configured as a prerequisite.

API quick reference

Has user APIYes
Auth methodOAuth 2.0 (SAML Bearer Assertion) or Basic Authentication (deprecated for production)
Base URLOfficial docs
SCIM availableYes
SCIM plan requiredEnterprise (SCIM provisioning requires SAP Identity Provisioning Service, which is included in SAP BTP enterprise agreements; SCIM is disabled by default and must be enabled via SAP support ticket)

Authentication

Auth method: OAuth 2.0 (SAML Bearer Assertion) or Basic Authentication (deprecated for production)

Setup steps

  1. In SAP Sales Cloud, navigate to Administrator > OAuth2.0 Client Registration and register an OAuth client.
  2. Configure the OAuth client with the appropriate scopes and note the Client ID and Client Secret.
  3. For SAML Bearer flow: obtain a SAML assertion from your IdP and exchange it at the token endpoint: POST https://.crm.ondemand.com/sap/bc/sec/oauth2/token.
  4. For client credentials flow (machine-to-machine): POST to the same token endpoint with grant_type=client_credentials, client_id, and client_secret.
  5. Include the resulting Bearer token in the Authorization header for all API requests.
  6. For SCIM provisioning via SAP Identity Provisioning Service (IPS): configure SAP Sales Cloud as a target system in IPS, provide the tenant URL, admin credentials or OAuth details, and enable the connector.

Required scopes

Scope Description Required for
UIWC:CC_HOME Basic access scope required for OData API calls in SAP Sales Cloud. All OData API operations
Not formally named per-resource in public docs SAP Sales Cloud OData API scopes are managed via Work Center access and business role assignments rather than named OAuth scopes. The OAuth client inherits the permissions of the associated technical user. User read/write operations via OData

User object / data model

Field Type Description On create On update Notes
ObjectID string System-generated unique identifier for the employee/user record. auto-generated immutable Used as the key in OData URLs.
EmployeeID string Business key / employee number. required optional Must be unique within the tenant.
FirstName string User's first name. required optional
LastName string User's last name. required optional
Email string Primary email address. required optional Used for login and notifications.
UserName string Login username for the SAP Sales Cloud tenant. required optional Must be unique. Used as the SCIM userName attribute.
UserValidityStartDate datetime Date from which the user account is valid. optional optional Edm.DateTime format.
UserValidityEndDate datetime Date on which the user account expires. optional optional Set to deactivate/expire a user account.
EmployeeRoleCode string Role code assigned to the employee (e.g., sales rep, manager). optional optional Mapped to business roles within SAP Sales Cloud.
Department string Department the user belongs to. optional optional
ManagerID string ObjectID of the user's manager. optional optional Used for org hierarchy.
MobilePhone string Mobile phone number. optional optional
Phone string Business phone number. optional optional
LanguageCode string Preferred language code (e.g., EN, DE). optional optional ISO 639-1 language codes.
CountryCode string Country code for the user. optional optional ISO 3166-1 alpha-2.
TimeZoneCode string User's time zone. optional optional
UserLock boolean Indicates whether the user account is locked. optional optional Set to true to lock/disable the user.
SalesOrganisationID string Sales organization the user is assigned to. optional optional

Core endpoints

List Users (EmployeeCollection)

  • Method: GET
  • URL: https://<tenant>.crm.ondemand.com/sap/c4c/odata/v1/c4codataapi/EmployeeCollection
  • Watch out for: Default page size is 1000; use $top and $skip for pagination. Response is OData v2 JSON wrapped in d.results.

Request example

GET /sap/c4c/odata/v1/c4codataapi/EmployeeCollection?$top=100&$skip=0&$format=json
Authorization: Bearer <token>

Response example

{
  "d": {
    "results": [
      {
        "ObjectID": "00163E0A...",
        "EmployeeID": "E001",
        "FirstName": "Jane",
        "LastName": "Doe",
        "Email": "jane.doe@example.com",
        "UserName": "jane.doe"
      }
    ]
  }
}

Get Single User

  • Method: GET
  • URL: https://<tenant>.crm.ondemand.com/sap/c4c/odata/v1/c4codataapi/EmployeeCollection('<ObjectID>')
  • Watch out for: ObjectID is the system key, not EmployeeID. Use $filter=EmployeeID eq 'E001' to look up by business key.

Request example

GET /sap/c4c/odata/v1/c4codataapi/EmployeeCollection('00163E0A...')?$format=json
Authorization: Bearer <token>

Response example

{
  "d": {
    "ObjectID": "00163E0A...",
    "EmployeeID": "E001",
    "FirstName": "Jane",
    "LastName": "Doe",
    "Email": "jane.doe@example.com"
  }
}

Create User

  • Method: POST
  • URL: https://<tenant>.crm.ondemand.com/sap/c4c/odata/v1/c4codataapi/EmployeeCollection
  • Watch out for: A CSRF token (X-CSRF-Token) must be fetched via a GET request with X-CSRF-Token: Fetch header before any write operation.

Request example

POST /sap/c4c/odata/v1/c4codataapi/EmployeeCollection
Content-Type: application/json
Authorization: Bearer <token>

{"EmployeeID":"E002","FirstName":"John","LastName":"Smith","Email":"john.smith@example.com","UserName":"john.smith"}

Response example

{
  "d": {
    "ObjectID": "00163E0B...",
    "EmployeeID": "E002",
    "FirstName": "John",
    "LastName": "Smith"
  }
}

Update User (Merge/Patch)

  • Method: PATCH
  • URL: https://<tenant>.crm.ondemand.com/sap/c4c/odata/v1/c4codataapi/EmployeeCollection('<ObjectID>')
  • Watch out for: SAP OData v2 uses X-HTTP-Method: MERGE for partial updates in some clients. PATCH is supported but verify tenant OData version behavior. Always include X-CSRF-Token.

Request example

PATCH /sap/c4c/odata/v1/c4codataapi/EmployeeCollection('00163E0B...')
Content-Type: application/json
X-CSRF-Token: <token>
Authorization: Bearer <token>

{"MobilePhone":"+1-555-0100"}

Response example

HTTP 204 No Content

Deactivate / Lock User

  • Method: PATCH
  • URL: https://<tenant>.crm.ondemand.com/sap/c4c/odata/v1/c4codataapi/EmployeeCollection('<ObjectID>')
  • Watch out for: SAP Sales Cloud does not support hard-delete of user records via API in most configurations. Deactivation is done via UserLock=true or setting UserValidityEndDate to a past date.

Request example

PATCH /sap/c4c/odata/v1/c4codataapi/EmployeeCollection('00163E0B...')
Content-Type: application/json
X-CSRF-Token: <token>
Authorization: Bearer <token>

{"UserLock":true}

Response example

HTTP 204 No Content

Filter Users by Email

  • Method: GET
  • URL: https://<tenant>.crm.ondemand.com/sap/c4c/odata/v1/c4codataapi/EmployeeCollection?$filter=Email eq 'jane.doe@example.com'&$format=json
  • Watch out for: Not all fields are filterable. Refer to the API Business Hub metadata ($metadata) to confirm filterable properties.

Request example

GET /sap/c4c/odata/v1/c4codataapi/EmployeeCollection?$filter=Email%20eq%20'jane.doe@example.com'&$format=json
Authorization: Bearer <token>

Response example

{
  "d": {
    "results": [
      {"ObjectID": "00163E0A...", "Email": "jane.doe@example.com"}
    ]
  }
}

Fetch CSRF Token

  • Method: GET
  • URL: https://<tenant>.crm.ondemand.com/sap/c4c/odata/v1/c4codataapi
  • Watch out for: The CSRF token and session cookie must both be included in subsequent POST/PATCH/DELETE requests. Tokens expire with the session.

Request example

GET /sap/c4c/odata/v1/c4codataapi
X-CSRF-Token: Fetch
Authorization: Bearer <token>

Response example

HTTP 200 OK
X-CSRF-Token: <csrf-token-value>
Set-Cookie: sap-usercontext=...

Batch Request

  • Method: POST
  • URL: https://<tenant>.crm.ondemand.com/sap/c4c/odata/v1/c4codataapi/$batch
  • Watch out for: Use $batch to reduce API call volume. SAP recommends batch for bulk provisioning scenarios.

Request example

POST /sap/c4c/odata/v1/c4codataapi/$batch
Content-Type: multipart/mixed; boundary=batch_001
X-CSRF-Token: <token>

--batch_001
Content-Type: application/http
GET EmployeeCollection('00163E0A...')
--batch_001--

Response example

HTTP 202 Accepted
multipart/mixed response with individual operation results

Rate limits, pagination, and events

  • Rate limits: SAP does not publicly document specific rate limits for SAP Sales Cloud OData APIs. Throttling behavior is tenant-specific and managed at the infrastructure level.

  • Rate-limit headers: No

  • Retry-After header: No

  • Rate-limit notes: No publicly documented rate limit headers or Retry-After behavior found in official SAP Sales Cloud API documentation. SAP recommends batching OData requests using $batch to reduce call volume.

  • Pagination method: offset

  • Default page size: 1000

  • Max page size: 1000

  • Pagination pointer: $skip / $top

  • Webhooks available: No

  • Webhook notes: SAP Sales Cloud does not natively expose outbound webhooks for user lifecycle events in the traditional sense. Event-driven integration is achieved via SAP Integration Suite (Cloud Integration / Event Mesh) or by polling the OData API.

  • Alternative event strategy: Use SAP Integration Suite / SAP Cloud Integration to subscribe to SAP Sales Cloud business events and forward them to external systems. Alternatively, poll EmployeeCollection with $filter on ChangedOn timestamp for delta detection.

SCIM API status

  • SCIM available: Yes

  • SCIM version: 2.0

  • Plan required: Enterprise (SCIM provisioning requires SAP Identity Provisioning Service, which is included in SAP BTP enterprise agreements; SCIM is disabled by default and must be enabled via SAP support ticket)

  • Endpoint: SCIM endpoint is not a direct tenant URL; provisioning is mediated by SAP Identity Provisioning Service (IPS). The IPS connector for SAP Sales Cloud uses the OData API internally. The IPS admin console is at: https://ipsproxy.accounts400.ondemand.com/ips/

  • Supported operations: Create User, Read User, Update User, Deactivate User, Read Groups (Business Roles), Assign User to Group

Limitations:

  • SCIM is not exposed as a direct endpoint on the SAP Sales Cloud tenant; it is mediated through SAP Identity Provisioning Service (IPS).
  • SCIM must be explicitly enabled by raising an SAP support ticket; it is disabled by default.
  • SSO (SAML) must be configured as a prerequisite before SCIM provisioning can be activated.
  • Hard delete of users is not supported; deprovisioning sets UserLock=true or adjusts validity dates.
  • Group/role provisioning support depends on IPS connector version and may require additional configuration.
  • Microsoft Entra ID (Azure AD) is the primary documented IdP for SCIM via IPS; other IdPs may require custom IPS configuration.
  • The IPS connector maps SCIM attributes to SAP Sales Cloud OData fields; custom attribute mappings require IPS transformation rules.

Common scenarios

Three integration patterns cover the primary lifecycle operations.

For direct provisioning, POST to EmployeeCollection with EmployeeID, FirstName, LastName, Email, UserName, LanguageCode, and EmployeeRoleCode after obtaining a Bearer token and a fresh CSRF token.

Business Role assignment may not be fully automatable via OData in all tenant configurations - verify against your tenant's $metadata for role assignment sub-entities.

For automated lifecycle management at scale, the IPS-mediated SCIM path is the supported route: configure SAP Sales Cloud as a target system in the IPS admin console, map SCIM attributes to OData fields via IPS transformation rules, and connect your IdP (Microsoft Entra ID is the primary documented source).

Attribute mapping errors in IPS transformation rules are the most common failure point;

review IPS job logs on any provisioning failure.

For deactivation, PATCH EmployeeCollection('') with {"UserLock": true} and optionally set UserValidityEndDate to the current date

hard delete is not supported via the OData API in standard configurations, and the record is retained for audit purposes.

When using IPS/SCIM, deprovisioning from the source IdP triggers the IPS job to set the lock flag automatically, keeping the identity graph consistent across connected systems.

Provision a new sales rep via OData API

  1. Authenticate: POST to OAuth token endpoint with client credentials or SAML Bearer to obtain Bearer token.
  2. Fetch CSRF token: GET /sap/c4c/odata/v1/c4codataapi with header X-CSRF-Token: Fetch; capture token and session cookie from response headers.
  3. Create employee: POST /sap/c4c/odata/v1/c4codataapi/EmployeeCollection with JSON body containing EmployeeID, FirstName, LastName, Email, UserName, LanguageCode, and EmployeeRoleCode.
  4. Verify creation: GET /sap/c4c/odata/v1/c4codataapi/EmployeeCollection?$filter=UserName eq 'new.user'&$format=json to confirm the record exists and capture ObjectID.
  5. Assign business role: Navigate to SAP Sales Cloud admin UI or use the BusinessRoleAssignment sub-entity if exposed in your tenant's $metadata.

Watch out for: Business role assignment may not be fully automatable via OData in all tenant configurations; verify $metadata for role assignment entities. CSRF token must be refreshed if the session expires.

Automate user lifecycle with SAP Identity Provisioning Service (SCIM)

  1. Raise an SAP support ticket to enable SCIM/IPS provisioning for your SAP Sales Cloud tenant.
  2. Configure SAML SSO between your IdP (e.g., Microsoft Entra ID) and SAP Sales Cloud as a prerequisite.
  3. In SAP IPS admin console, add SAP Sales Cloud as a target system and configure the connector with tenant URL, admin credentials or OAuth details.
  4. Configure attribute mappings in IPS transformation rules to map IdP user attributes (e.g., userName, emails, name) to SAP Sales Cloud OData fields.
  5. Add your IdP (e.g., Entra ID) as a source system in IPS and configure the SCIM provisioning job.
  6. Run a test provisioning job and verify users appear in SAP Sales Cloud EmployeeCollection.
  7. Enable scheduled provisioning jobs for ongoing sync.

Watch out for: IPS connector for SAP Sales Cloud uses the OData API internally, not a direct SCIM endpoint on the tenant. Attribute mapping errors in IPS transformation rules are a common failure point and require reviewing IPS job logs.

Deactivate a departed user

  1. Look up the user's ObjectID: GET /EmployeeCollection?$filter=Email eq 'departed@example.com'&$format=json.
  2. Fetch a fresh CSRF token via GET with X-CSRF-Token: Fetch header.
  3. Lock the account: PATCH /EmployeeCollection('') with body {"UserLock": true} and headers X-CSRF-Token and session cookie.
  4. Optionally set UserValidityEndDate to today's date for additional deactivation signal.
  5. Verify: GET the employee record and confirm UserLock is true.

Watch out for: Hard delete is not supported via the OData API in standard SAP Sales Cloud configurations. Locking the user prevents login but retains the record for audit/historical data purposes. If using IPS/SCIM, deprovisioning from the source IdP will trigger the IPS job to set the lock flag automatically.

Why building this yourself is a trap

Several non-obvious behaviors create integration risk. The ObjectID (system key) and EmployeeID (business key) are distinct - lookups by business key require $filter=EmployeeID eq 'E001'; passing EmployeeID where ObjectID is expected silently fails or returns no results.

Not all fields in EmployeeCollection are filterable; attempting $filter on a non-filterable field returns an error rather than an empty result set - always validate against the $metadata document. OAuth SAML Bearer Assertion flow requires a correctly configured trust relationship between the tenant and the IdP;

misconfigured trust produces 401 errors with minimal diagnostic detail. Tenant base URLs vary by data center region (e.g., .crm.ondemand.com, .crm.eu1.ondemand.com) - hardcoding the wrong base URL is a silent failure in multi-region deployments. The identity graph is only as current as the last IPS provisioning job run;

real-time sync requires polling EmployeeCollection with a $filter on the ChangedOn timestamp as a delta detection fallback, since SAP Sales Cloud does not natively expose outbound webhooks for user lifecycle events.

Automate SAP Sales Cloud workflows without one-off scripts

Stitchflow builds and maintains end-to-end IT automation across your SaaS stack, including apps without APIs. Built for exactly how your company works, with human approvals where they matter.

Every app coverage, including apps without APIs
60+ app integrations plus browser automation for apps without APIs
IT graph reconciliation across apps and your IdP
Less than a week to launch, maintained as APIs and admin consoles change
SOC 2 Type II. ~2 hours of your team's time

UpdatedMar 16, 2026

* Details sourced from official product documentation and admin references.

Keep exploring

Related apps

15Five logo

15Five

Full API + SCIM
AutomationAPI + SCIM
Last updatedFeb 2026

15Five uses a fixed role-based permission model with six predefined roles: Account Admin, HR Admin, Billing Admin, Group Admin, Manager, and Employee. No custom roles can be constructed. User management lives at Settings gear → People → Manage people p

1Password logo

1Password

Full API + SCIM
AutomationAPI + SCIM
Last updatedFeb 2026

1Password's admin console at my.1password.com covers the full user lifecycle — invitations, group assignments, vault access, suspension, and deletion — without any third-party tooling. Like every app that mixes role-based and resource-level permissions

8x8 logo

8x8

Full API + SCIM
AutomationAPI + SCIM
Last updatedFeb 2026

8x8 Admin Console supports full lifecycle user management — create, deactivate, and delete — across its X Series unified communications platform. Every app a user can access (8x8 Work desktop, mobile, web, Agent Workspace) is gated by license assignmen