SCIM 2.0 User Provisioning

This feature is currently in Beta for selected customers on the Intelligent package. If your organization is interested in participating, contact your Account Manager (CSM).

SCIM 2.0 lets your identity provider (IdP) automatically manage Emplifi users — creating accounts, updating details, and revoking access — without manual intervention. This guide walks you through setting up the integration and managing users and teams through SCIM.

Before you begin

  • An active Emplifi account on the Intelligent package with SCIM enabled.

  • Platform Admin access in Emplifi. Only Platform Admins can access the User Provisioning settings and generate the bearer token.

  • An identity provider that supports SCIM 2.0 over HTTPS (for example, Okta, Microsoft Entra ID, or OneLogin).

What is SCIM?

System for Cross-domain Identity Management (SCIM 2.0) is an open standard (RFC 7644) that connects your IdP to Emplifi. Once connected, your IT team can manage the full user lifecycle — onboarding, role changes, and offboarding — from the same place they manage every other tool in your organization.

When a new employee joins, they get access to Emplifi automatically. When they leave, access is removed. There are no manual steps in between. For enterprise teams managing large numbers of users across multiple social and CX workflows, this reduces administrative overhead, strengthens security, and helps meet internal compliance requirements.

Base URL

All SCIM requests go to:

https://account.emplifi.io/api/scim/v2

Set up the integration

Generate a bearer token

A Platform Admin must generate a bearer token to authenticate your IdP with Emplifi.

  1. Navigate to Account Settings > User Provisioning.

  2. Click Set up SCIM.

  3. Copy the bearer token immediately and paste it into your IdP.

After setup, the page shows the SCIM URL, a masked version of the token, and the creation and last-used dates. You can rotate or remove the integration from this page at any time.

The token is shown in full only when it's first generated. If you navigate away before copying it, rotate the token to get a new one.

Token format

Bearer tokens always begin with ems_ followed by a base64url-encoded payload. For example:

ems_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_

Rotate the token

To rotate a compromised or expired token, navigate to Account Settings > User Provisioning and select the rotation option. The old token is invalidated immediately — update your IdP before the next sync to prevent provisioning failures.

Authentication

If you're using Okta, Microsoft Entra ID, or another standard IdP, you only need to paste your bearer token once during setup. The IdP then includes it and all required headers automatically in every request.

Every SCIM request must include:

Authorization: Bearer <your-bearer-token>
Accept: application/scim+json

Requests with a body (POST, PUT, PATCH) must also include:

Content-Type: application/scim+json

Missing or invalid tokens return 401 Unauthorized.

Rate limiting

Requests are rate-limited per integration:

Parameter

Default

Window

60 seconds

Max requests per window

100

Exceeding the limit returns 429 Too Many Requests. If you're hitting this consistently, contact your Account Manager (CSM) to discuss a higher limit.

Supported operations

Operation

Supported

What this means

Create user (POST /Users)

✅

Creates a new user account in your Emplifi account

Update user (PUT /Users/:id, PATCH /Users/:id)

✅

Updates an existing user's details or platform access

Deactivate / reactivate (active attribute)

✅

Suspends or restores a user's access without removing their account

Delete user (DELETE /Users/:id)

✅

Permanently removes a user from your Emplifi account

Assign users to teams (PATCH /Users)

✅

Adds or removes a user from a team and sets their team role

List users (GET /Users)

✅ Read-only

Retrieves all active users in your account

Filter by id or externalId

✅ Read-only

Looks up a specific user by their Emplifi ID or your IdP's identifier

Get single user (GET /Users/:id)

✅ Read-only

Retrieves a specific user's details

List teams as groups (GET /Groups)

✅ Read-only

Retrieves all teams in your account

Get single team as group (GET /Groups/:id)

✅ Read-only

Retrieves details and members of a specific team

Bulk operations (POST /Bulk)

❌ Not supported

—

/Me endpoint

❌ Not supported

—

Create / modify / delete groups (teams)

❌ Not supported

—

Password management

❌ Not supported

—

Sorting

❌ Not supported

—

ETags

❌ Not supported

—

Provision users

Create a user

JSON
POST /api/scim/v2/Users

Authorization: Bearer <token>
Content-Type: application/scim+json
Accept: application/scim+json

{
  "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
  "userName": "jane.doe@example.com",
  "name": {
    "givenName": "Jane",
    "familyName": "Doe"
  },
  "externalId": "idp-user-id-12345",
  "emails": [
    { "value": "jane.doe@example.com", "primary": true, "type": "work" }
  ],
  "active": true,
  "roles": [
    { "value": "platform_user" }
  ]
}

How email is resolved

Emplifi determines the email address for the new account in this order:

  1. If userName contains @, use userName (lowercased and trimmed).

  2. Otherwise, use the primary entry in emails[].

  3. Otherwise, use the first entry in emails[].

  4. If none is found, the request returns 400 Bad Request.

Response

JSON
HTTP/1.1 201 Created
Content-Type: application/scim+json

{
  "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
  "id": "acl-user-id-abc123",
  "externalId": "idp-user-id-12345",
  "userName": "jane.doe@example.com",
  "name": { "givenName": "Jane", "familyName": "Doe" },
  "emails": [
    { "value": "jane.doe@example.com", "type": "work", "primary": true }
  ],
  "active": true,
  "roles": [
    { "value": "platform_user", "display": "Platform User", "primary": false }
  ],
  "groups": [],
  "meta": { "resourceType": "User" }
}

The id in the response is Emplifi's internal user ID. Use this as the resource ID for all subsequent PUT, PATCH, and DELETE requests.

Error codes

Status

Cause

201

User created successfully

400

active: false on create, or no resolvable email

401

Invalid or missing bearer token

409

A user with this email already exists in the account

429

Rate limit exceeded

500

Internal error (Suite invite failure)

User attribute mapping

SCIM attribute

Emplifi field

Notes

id

Emplifi user ID

Read-only; set by Emplifi on create

externalId

Stored per-integration

Returned in egress; used for externalId filter lookups

userName

Used as email if it contains @

Lowercased and trimmed

name.givenName

First name

Trimmed

name.familyName

Last name

Trimmed

emails[primary=true].value

Email

Fallback if userName has no @

active

Account active status

false deactivates; true or omitted = active

roles[].value

Platform access

See Platform access levels below

groups[].value

Team membership

Read/write. Reflects current team memberships; include in provisioning payload to assign teams

Attributes not listed above are ignored on ingest.

Platform access levels

Emplifi supports two platform access levels via SCIM:

roles[].value

Emplifi access level

roles[].display returned

platform_admin

Platform Admin (Account Admin)

Platform Admin

platform_user (default)

Regular user (Account User)

Platform User

Your Account Manager (CSM) can configure custom value strings to match your IdP's role names. For example, if your IdP sends Administrator instead of platform_admin, ask your CSM to set platform_admin_role_value: "Administrator" in the integration config.

  • On create: The access level is applied immediately after the user is invited.

  • On update: If the access level in the SCIM payload differs from the user's current level, it's updated automatically.

  • If roles is omitted: The user is assigned platform_user by default.

Update users

Both PUT and PATCH update an existing user by Emplifi user ID:

PUT  /api/scim/v2/Users/<emplifi-user-id>
PATCH /api/scim/v2/Users/<emplifi-user-id>

Attribute

Updated on PUT/PATCH?

active

✅ Activates or deactivates the account

roles

✅ Updates platform access if changed

externalId

✅ Updates stored mapping

name, emails

Stored in SCIM properties (used for egress fidelity)

groups (team membership + team role)

✅ Adds or removes team memberships and updates team role

Email address (userName)

❌ Cannot be changed via SCIM

Deactivate a user

JSON
PATCH /api/scim/v2/Users/<id>
Content-Type: application/scim+json

{
  "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
  "Operations": [
    { "op": "replace", "path": "active", "value": false }
  ]
}

Deactivated users remain in the Emplifi account but can't sign in. They're not returned in GET /Users responses by default, and no personally identifiable information (name, email, profile picture) is returned for deactivated users.

Reactivate a user

JSON
PATCH /api/scim/v2/Users/<id>
Content-Type: application/scim+json

{
  "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
  "Operations": [
    { "op": "replace", "path": "active", "value": true }
  ]
}

Error codes for updates

Status

Cause

200

Update applied

204

PATCH applied with no response body

401

Invalid or missing bearer token

404

User not found in your account

429

Rate limit exceeded

Remove users

DELETE /api/scim/v2/Users/<emplifi-user-id>

Authorization: Bearer <token>
Accept: application/scim+json

This removes the user from the Emplifi account. Their data (posts, content, history) is not deleted — only their account membership is removed.

Status

Cause

204

User removed successfully

401

Invalid or missing bearer token

404

User not found in your account

429

Rate limit exceeded

500

Internal error during removal

Read users and teams

List all users

GET /api/scim/v2/Users

Authorization: Bearer <token>
Accept: application/scim+json

Returns a SCIM ListResponse with all active users in your account. Maximum 100 results per page. Deactivated users are not returned by default.

Get a single user

GET /api/scim/v2/Users/<emplifi-user-id>

Filter users

GET /api/scim/v2/Users?filter=externalId%20eq%20%22idp-user-id-12345%22
GET /api/scim/v2/Users?filter=id%20eq%20%22acl-user-id-abc123%22

Teams

Emplifi Teams are exposed as SCIM Groups. Your IdP can read the list of teams, see which users are members, and assign or remove users from teams as part of the provisioning and update flows. Teams themselves cannot be created, renamed, or deleted via SCIM.

Team Role is set via a custom schema extension on group membership. The role attribute carries the team role name (for example, Team Admin or Team User).

  • If the role attribute is omitted when adding a user to a team, the default Team User role is assigned. You can update the role manually in Emplifi afterwards.

  • Removing a team from a user's SCIM payload removes their membership in that team in Emplifi.

  • Referencing a team or team role that doesn't exist in the account returns a SCIM error.

List all teams

GET /api/scim/v2/Groups

Authorization: Bearer <token>
Accept: application/scim+json

Get a single team

GET /api/scim/v2/Groups/<group-id>

Group response example

JSON
{
  "schemas": [
    "urn:ietf:params:scim:schemas:core:2.0:Group",
    "urn:emplifi:params:scim:schemas:extension:2.0:Group"
  ],
  "id": "team-id-xyz",
  "displayName": "EMEA Social Team",
  "members": [
    {
      "value": "acl-user-id-abc123",
      "display": "Jane Doe",
      "urn:emplifi:params:scim:schemas:extension:2.0:Group": {
        "role": "Team Admin"
      }
    }
  ]
}

Assign a user to a team

Include the groups array in a create (POST) or update (PATCH/PUT) request to assign team membership. The recommended approach is to include groups in the initial POST request so the user lands in the correct team from the start.

JSON
PATCH /api/scim/v2/Users/<emplifi-user-id>

{
  "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
  "Operations": [
    {
      "op": "add",
      "path": "groups",
      "value": [
        {
          "value": "team-id-xyz",
          "urn:emplifi:params:scim:schemas:extension:2.0:Group": {
            "role": "Team Admin"
          }
        }
      ]
    }
  ]
}

To remove a user from a team, send a PATCH with op: remove targeting that group, or omit the team from the groups array in a PUT request.

Discovery endpoints

These endpoints let your IdP auto-discover what the SCIM server supports. Most IdPs call them automatically during setup.

Endpoint

Purpose

GET /ServiceProviderConfig

Returns supported features (filtering, sorting, bulk, etc.)

GET /ResourceTypes

Lists available resource types (User, Group)

GET /Schemas

Returns schema definitions including custom extensions

Connect your identity provider

Okta

  1. In your Okta Admin Console, navigate to Applications > Browse App Catalog and find or create a SCIM 2.0 app.

  2. Under Provisioning > Integration, set:

    • SCIM connector base URL: https://account.emplifi.io/api/scim/v2

    • Unique identifier field for users: userName

    • Authentication Mode: HTTP Header

    • Authorization: Bearer <your-bearer-token>

  3. Click Test Connector Configuration. Okta calls GET /Users to verify connectivity.

  4. Turn on the provisioning features you need: Push New Users, Push Profile Updates, Deactivate Users.

  5. Assign users or groups to the app to begin syncing.

Okta sends the id from the SCIM server back as the Okta external ID. Make sure your app mapping uses id (not externalId) as the identifier.

Microsoft Entra ID (Azure AD)

  1. In Azure AD, navigate to Enterprise Applications > New application > Create your own application.

  2. Select Integrate any other application you don't find in the gallery.

  3. Under Provisioning, set Provisioning Mode to Automatic.

  4. Under Admin Credentials, enter:

    • Tenant URL: https://account.emplifi.io/api/scim/v2

    • Secret Token: <your-bearer-token>

  5. Click Test Connection.

  6. Under Mappings, verify the attribute mapping:

    • userPrincipalName → userName

    • givenName → name.givenName

    • surname → name.familyName

    • IsSoftDeleted → active (negated)

  7. Set Provisioning Status to On and save.

Using a different identity provider?

The setup process is the same across most SCIM 2.0-compatible IdPs — you'll need the SCIM base URL and your bearer token. Refer to your IdP's official documentation for configuration instructions:

If your IdP is not listed here or you need help with the configuration, contact your Account Manager (CSM).

Troubleshooting

401 Unauthorized

Symptoms: All SCIM requests fail with a 401 error.

Why this happens: The bearer token in your IdP configuration is missing, malformed, or has been invalidated — typically after a token rotation.

How to fix: Navigate to Account Settings > User Provisioning to confirm your token is active. If it was recently rotated, update your IdP configuration with the new token. If the token is no longer visible, rotate it to get a new one, then update your IdP before the next sync.

409 Conflict on user create

Symptoms: A create request returns 409 Conflict.

Why this happens: A user with this email already exists in the Emplifi account — most likely added manually before SCIM was set up.

How to fix: Either remove the user from the account manually and retry provisioning, or link the existing Emplifi account to the IdP record by sending a PATCH request to /Users/<emplifi-user-id> with the user's externalId from your IdP.

404 on PUT/PATCH/DELETE

Symptoms: An update or delete request returns 404 Not Found.

Why this happens: The Emplifi user ID in the request path doesn't match any user in your account. This can happen if the user was removed outside of SCIM (for example, deleted manually in Emplifi) and your IdP still has the old ID cached.

How to fix: Trigger a re-sync from your IdP to refresh the user list, or re-provision the user by sending a new POST /Users request.

User created but not assigned to the expected team

Symptoms: A user is provisioned but doesn't appear in any team.

Why this happens: Team assignment requires the groups attribute to be included in the SCIM payload. If it was omitted, the user is provisioned but not placed in any team.

How to fix: To assign a team from the start, include the groups attribute in the initial POST /Users request with the team ID and desired team role — this is the recommended approach. If the user already exists, send a PATCH request to /Users/<emplifi-user-id> with the groups attribute. Use GET /Groups to retrieve the correct team ID if needed.

Platform access not updating

Symptoms: A user's platform access level doesn't change after a PATCH or PUT.

Why this happens: The roles[].value sent by your IdP doesn't match the values Emplifi expects. The comparison is case-sensitive, and some IdPs send display names (for example, Administrator) instead of the SCIM values (platform_admin).

How to fix: Check that your IdP is sending exactly platform_admin or platform_user in the roles[].value field. If your IdP uses different role names, contact your Account Manager (CSM) to configure custom role value mappings.

429 Too Many Requests

Symptoms: Some SCIM requests return 429 errors during syncs.

Why this happens: Your IdP's sync job is sending more than 100 requests per 60 seconds, exceeding the rate limit. This is common during initial provisioning of large user directories.

How to fix: Your IdP should automatically back off and retry when it receives a 429 response. If you're hitting the limit consistently during normal operations, contact your Account Manager (CSM) to request a higher limit.