Skip to content
English - United Kingdom
  • There are no suggestions because the search field is empty.

Users API

1. Overview

The Users API allows you to create, retrieve, list, update, and deactivate users in SpeakUp via the SCIM 2.0 protocol. It is designed for use by enterprise identity providers (IdPs) such as Microsoft Entra ID, Okta, and OneLogin to automate user lifecycle management.

Base Endpoint: {API_BASE_URL}/scim/v2/Users


2. Before You Begin

Review the following requirements and behavioral notes before configuring provisioning in your identity provider. Understanding these constraints upfront prevents common provisioning failures.

2.1 Supported Provisioning Features 

Feature

 

Supported

 

Notes

 

Create users

✅ Yes

Via POST /scim/v2/Users

Update user attributes

✅ Yes

Via PUT or PATCH

Deactivate users

✅ Yes

Set active: false via PATCH

Reactivate users

✅ Yes

Set active: true via PATCH

Delete users

❌ No

SpeakUp does not support user deletion via SCIM. Use deactivation instead.

Sync group membership

✅ Yes

Via Groups API

Filter users by attribute

✅ Yes

userName, displayName, active

Paginated user listing

✅ Yes

startIndex and count parameters

Multiple emails per user

❌ No

SpeakUp stores one email per user

Multiple phone numbers per user

❌ No

SpeakUp stores one phone number per user

 
2.2 Required Fields for User Provisioning
 

Three attributes are mandatory for every user creation request. Your identity provider must be configured to send all three.

 

Attribute

 

Type

 

Constraint

 

userName

string

Must be a valid email address. Used as the unique identifier.

displayName

string

The name shown in the SpeakUp UI.

active

boolean

Account state at creation. Typically true.

 
 

Important: The userName value must be a valid email address. It serves as the authoritative email for the user account. If an emails array is also present in the request, SpeakUp uses userName as the stored email and gracefully ignores any conflicting values in the array.

2.3 Key Behavioral Constraints

Before provisioning users at scale, be aware of how SpeakUp handles data that your IdP may send in different formats.

One identity per user. SpeakUp enforces a single email address and a single phone number per user account. If your IdP sends arrays with multiple entries, SpeakUp applies the priority rules described in sections 2.5 and 2.6 to determine which value to store.

userName is the unique key. Attempting to create a user with a userName that already exists returns 409 Conflict.

User deletion is not supported. SpeakUp does not support permanent deletion of users via the SCIM API. A DELETErequest will be accepted but the user will be deactivated rather than removed. For all offboarding scenarios, set active: false via a PATCH request. This preserves the account for audit and historical data purposes and allows reactivation if needed.

externalId is sourced from your identity provider. SpeakUp stores the externalId value as received from the provisioning request and uses it to correlate accounts with your external identity provider. It is not used as a lookup key internally — SpeakUp identifies users by its own system-generated id returned at creation time.

2.4 Name Resolution Priority

SpeakUp stores a single name field internally. When a provisioning request includes multiple name-related attributes, SpeakUp resolves the display name using the following priority order:

  1. displayName (highest priority — always send this)

  2. name.formatted

  3. name.givenName + name.familyName (concatenated)

Most identity providers send displayName by default. If your IdP attribute mapping omits displayName, verify that name.formatted or the given/family name combination is present, or the user may be created with a blank display name.

2.5 Email Resolution Priority

When the provisioning request includes both userName and an emails array, SpeakUp determines the stored email as follows:

  1. userName (highest priority)

  2. emails[].value where primary: true

  3. emails[0].value

Because userName takes precedence, ensure your IdP maps the user's primary email to userName. Sending a different address in the emails array does not override the userName value.

2.6 Phone Number Resolution Priority

When multiple phone numbers are provided:

  1. phoneNumbers[].value where primary: true

  2. phoneNumbers[0].value

If no phone number is included, SpeakUp returns an empty array [] in API responses.


3. Authentication

All SCIM API requests must include a bearer token in the Authorization header. Refer to the SpeakUp SCIM Overview for token generation instructions.

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

4. Response Structure

4.1 Core User Attributes
 

Attribute

 

Type

 

Description

 

id

string

System-generated unique identifier. Read-only. Returned on creation.

userName

string

Unique email address. Used as the primary identifier. Required.

displayName

string

Name shown in the SpeakUp UI. Required.

active

boolean

Whether the account is active. Required.

name.formatted

string

Full name as a single string.

name.givenName

string

First name.

name.familyName

string

Last name.

emails[].value

string

Email address. Must match userName.

emails[].type

string

Always "work" in responses.

emails[].primary

boolean

Always true in responses.

phoneNumbers[].value

string

Phone number.

phoneNumbers[].type

string

Always "work" in responses.

phoneNumbers[].primary

boolean

Always true in responses.

title

string

Job title.

userType

string

User category (e.g., "Employee", "Contractor").

externalId

string

External identifier from HR system or IdP.

preferredLanguage

string

BCP 47 language tag. Defaults to "en-GB".

groups[].value

string

Group ID. Returned in responses.

groups[].display

string

Group name. Returned in responses.

groups[].$ref

string

Full URL to the Group resource. Returned in responses.

meta.resourceType

string

Always "User".

meta.created

string

ISO 8601 timestamp of creation.

meta.lastModified

string

ISO 8601 timestamp of last update.

meta.location

string

Canonical URL of this User resource.

 
4.2 Enterprise Extension Attributes

To provision organizational attributes such as department or manager, include the enterprise extension schema (urn:ietf:params:scim:schemas:extension:enterprise:2.0:User) in the schemas array.

 

Attribute

 

SpeakUp Field

 

Type

 

Description

 

employeeNumber

employeeNumber

string

Employee ID from HR system. Max 128 characters.

costCenter

costCentreId

option-list

Cost center for billing allocation.

department

departmentId

option-list

Department name.

division

divisionId

option-list

Division name.

organization

organizationId

option-list

Organization or company name.

manager

managerId

complex

Reference to another user: value (user ID), $ref (User URL), displayName.

 

Note: Fields mapped to option-list types (department, division, costCenter, organization) are matched against existing values configured in your SpeakUp instance. If a value is not found, SpeakUp will create a new option-list item using the provided value.


5. Create a User

Method: POST
Endpoint: /scim/v2/Users

5.1 Minimal Request
curl -X POST 'https://your-org.speakup.com/scim/v2/Users' \ -H 'Content-Type: application/scim+json' \ -H 'Accept: application/scim+json' \ -H 'Authorization: Bearer <ACCESS_TOKEN>' \ --data-raw '{ "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"], "userName": "john.doe@example.com", "displayName": "John Doe", "active": true }'
 
5.2 Request with Name and Email
curl -X POST 'https://your-org.speakup.com/scim/v2/Users' \ -H 'Content-Type: application/scim+json' \ -H 'Accept: application/scim+json' \ -H 'Authorization: Bearer <ACCESS_TOKEN>' \ --data-raw '{ "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"], "userName": "john.doe@example.com", "displayName": "John Doe", "active": true, "name": { "givenName": "John", "familyName": "Doe", "formatted": "John Doe" }, "emails": [ { "value": "john.doe@example.com", "type": "work", "primary": true } ] }'
 
5.3 Request with Enterprise Extension
curl -X POST 'https://your-org.speakup.com/scim/v2/Users' \ -H 'Content-Type: application/scim+json' \ -H 'Accept: application/scim+json' \ -H 'Authorization: Bearer <ACCESS_TOKEN>' \ --data-raw '{ "schemas": [ "urn:ietf:params:scim:schemas:core:2.0:User", "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User" ], "userName": "jane.doe@company.com", "displayName": "Jane Doe", "active": true, "name": { "givenName": "Jane", "familyName": "Doe" }, "emails": [ { "value": "jane.doe@company.com", "type": "work", "primary": true } ], "title": "Product Manager", "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User": { "employeeNumber": "EMP-99999", "costCenter": "Product", "department": "Product Management", "division": "Product Division" } }'

 

5.4 Response — 201 Created
{ "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"], "id": "101", "userName": "john.doe@example.com", "displayName": "John Doe", "active": true, "name": { "givenName": "John", "familyName": "Doe", "formatted": "John Doe" }, "emails": [ { "value": "john.doe@example.com", "type": "work", "primary": true } ], "title": "Senior Software Engineer", "phoneNumbers": [ { "value": "+1-555-0123", "type": "work", "primary": true } ], "preferredLanguage": "en", "meta": { "resourceType": "User", "created": "2026-02-23T10:30:00Z", "lastModified": "2026-02-23T10:30:00Z", "location": "https://your-org.speakup.com/scim/v2/Users/101" } }

 

5.5 Error Responses

400 Bad Request — Missing or invalid required fields:

{ "schemas": ["urn:ietf:params:scim:api:messages:2.0:Error"], "scimType": "invalidValue", "detail": "Validation failed: userName is required", "status": "400" }

409 Conflict — A user with the same userName already exists:

 
{ "schemas": ["urn:ietf:params:scim:api:messages:2.0:Error"], "scimType": "uniqueness", "detail": "A user with userName 'john.doe@example.com' already exists", "status": "409" }

6. Retrieve a User

Method: GET
Endpoint: /scim/v2/Users/{id}

6.1 Query Parameters

Parameter

 

Type

 

Description

 

excludedAttributes

string

Comma-separated list of attributes to omit from the response (e.g., meta).

 
6.2 Request
curl -X GET 'https://your-org.speakup.com/scim/v2/Users/101' \ -H 'Accept: application/scim+json' \ -H 'Authorization: Bearer <ACCESS_TOKEN>'

 

6.3 Request (with excludedAttributes)
curl -X GET 'https://your-org.speakup.com/scim/v2/Users/101?excludedAttributes=meta' \ -H 'Accept: application/scim+json' \ -H 'Authorization: Bearer <ACCESS_TOKEN>'

 

6.4 Response — 200 OK
{ "schemas": ["urn:ietf:params:scim:api:messages:2.0:ListResponse"], "totalResults": 1, "startIndex": 1, "itemsPerPage": 1, "Resources": [ { "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"], "id": "101", "userName": "john.doe@example.com", "displayName": "John Doe", "active": true, "name": { "givenName": "John", "familyName": "Doe", "formatted": "John Doe" }, "emails": [ { "value": "john.doe@example.com", "type": "work", "primary": true } ], "title": "Senior Software Engineer", "phoneNumbers": [ { "value": "+1-555-0123", "type": "work", "primary": true } ], "preferredLanguage": "en", "groups": [ { "value": "1", "display": "Engineering Team", "$ref": "https://your-org.speakup.com/scim/v2/Groups/1" } ], "meta": { "resourceType": "User", "created": "2026-02-23T10:30:00Z", "lastModified": "2026-02-23T10:30:00Z", "location": "https://your-org.speakup.com/scim/v2/Users/101" } } ] }

 

6.5 Error — 404 Not Found
{ "schemas": ["urn:ietf:params:scim:api:messages:2.0:Error"], "detail": "User not found", "status": "404" }

7. List Users

Method: GET
Endpoint: /scim/v2/Users

7.1 Query Parameters

Parameter

 

Type

 

Default

 

Description

 

startIndex

integer

1

1-based starting position for pagination.

count

integer

50

Number of results per page.

filter

string

SCIM filter expression (URL-encoded).

excludedAttributes

string

Comma-separated attributes to omit (e.g., meta).

  
7.2 Supported Filter Expressions
 

Filter Expression

 

Behavior

 

userName eq "john.doe@example.com"

Exact match on userName

userName sw "john"

userName starts with value

displayName co "Doe"

displayName contains value

displayName eq "John Doe"

Exact match on displayName

active eq true

Active users only

 
7.3 Request Examples
All users (default pagination):
curl -X GET 'https://your-org.speakup.com/scim/v2/Users' \ -H 'Accept: application/scim+json' \ -H 'Authorization: Bearer <ACCESS_TOKEN>'

 

With pagination 

curl -X GET 'https://your-org.speakup.com/scim/v2/Users?startIndex=1&count=10' \ -H 'Accept: application/scim+json' \ -H 'Authorization: Bearer <ACCESS_TOKEN>'

 

With filter: 

curl -X GET 'https://your-org.speakup.com/scim/v2/Users?filter=userName%20eq%20%22john.doe@example.com%22' \ -H 'Accept: application/scim+json' \ -H 'Authorization: Bearer <ACCESS_TOKEN>'

8. Update a User (Full Replacement — PUT)

Use PUT to fully replace a user's attributes. Attributes omitted from the request body may be cleared per SCIM semantics. Use PATCH if you only want to update specific fields.

Note: The same name, email, and phone resolution priority rules described in sections 2.4–2.6 apply to PUTrequests. userName always takes precedence as the stored email; displayName takes precedence for the stored name field.

Method: PUT
Endpoint: /scim/v2/Users/{id}

8.1 Request
curl -X PUT 'https://your-org.speakup.com/scim/v2/Users/101' \ -H 'Content-Type: application/scim+json' \ -H 'Accept: application/scim+json' \ -H 'Authorization: Bearer <ACCESS_TOKEN>' \ --data-raw '{ "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"], "userName": "john.doe@example.com", "displayName": "John Michael Doe", "active": true, "name": { "givenName": "John", "familyName": "Doe" }, "title": "Principal Software Engineer" }'
 
8.2 Response — 200 OK

Returns the full updated user in SCIM format, including updated meta.lastModified.

8.3 Error Responses
 

Code

 

Cause

 

400

Invalid or missing required fields

404

User does not exist

409

userName already in use by a different user

 
 
 

9. Update a User (Partial Update — PATCH)

Use PATCH to update one or more attributes without affecting others. This is the recommended method for lifecycle operations such as deactivation, reactivation, and attribute updates.

Note: The same name, email, and phone resolution priority rules described in sections 2.4–2.6 apply to PATCH requests. When updating userName, the stored email will be updated accordingly.

Method: PATCH
Endpoint: /scim/v2/Users/{id}

9.1 Update a Single Attribute 
curl -X PATCH 'https://your-org.speakup.com/scim/v2/Users/101' \ -H 'Content-Type: application/scim+json' \ -H 'Accept: application/scim+json' \ -H 'Authorization: Bearer <ACCESS_TOKEN>' \ --data-raw '{ "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"], "Operations": [ { "op": "replace", "path": "title", "value": "Engineering Manager" } ] }'

 

9.2 Update Multiple Attributes
curl -X PATCH 'https://your-org.speakup.com/scim/v2/Users/101' \ -H 'Content-Type: application/scim+json' \ -H 'Accept: application/scim+json' \ -H 'Authorization: Bearer <ACCESS_TOKEN>' \ --data-raw '{ "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"], "Operations": [ { "op": "replace", "path": "title", "value": "Engineering Manager" }, { "op": "replace", "path": "active", "value": true } ] }'

 

9.3 Deactivate a User
curl -X PATCH 'https://your-org.speakup.com/scim/v2/Users/101' \ -H 'Content-Type: application/scim+json' \ -H 'Accept: application/scim+json' \ -H 'Authorization: Bearer <ACCESS_TOKEN>' \ --data-raw '{ "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"], "Operations": [ { "op": "replace", "path": "active", "value": false } ] }'

 

9.4 Response — 200 OK

Returns the full user in SCIM format with updated attributes and meta.lastModified.


10. Status Code Reference

Code

 

Meaning

 

When It Occurs

 

200

OK

Successful GET, PATCH, or PUT

201

Created

Successful POST

400

Bad Request

Missing required fields, invalid data format, or malformed patch operation

401

Unauthorized

Invalid or missing access token

403

Forbidden

Insufficient permissions for the operation

404

Not Found

User ID does not exist

409

Conflict

Duplicate userName or constraint violation

500

Internal Server Error

Server-side error — contact SpeakUp support

 
 

11. Attribute Mapping Reference

11.1 Core Schema (urn:ietf:params:scim:schemas:core:2.0:User)
 

SpeakUp Field

 

SCIM Attribute

 

Type

 

Notes

 

id

id

string

Read-only. Returned by API.

email

userName

string

Required. Must be a valid email. Highest-priority source for stored email.

name

displayName

string

Required. Shown in UI. Highest-priority source for stored name.

name

name.formatted

string

Used if displayName is absent.

firstName

name.givenName

string

Used if neither displayName nor name.formatted is present.

lastName

name.familyName

string

Concatenated with name.givenName as last fallback for stored name.

enabled

active

boolean

Required.

email

emails[].value

string

Stored email derived from userName. Array accepted but userNametakes precedence.

jobTitle

title

string

phone

phoneNumbers[].value

string

See phone resolution priority in section 2.6.

preferredLanguage

preferredLanguage

string

BCP 47 language tag. Defaults to "en-GB".

externalId

externalId

string

Sourced from identity provider. Stored as received. Not used as an internal lookup key.

groups

groups

complex

Read-only in user responses. Managed via Groups API.

createdAt

meta.created

string (ISO 8601)

Read-only.

updatedAt

meta.lastModified

string (ISO 8601)

Read-only.

 

11.2 Enterprise Extension (urn:ietf:params:scim:schemas:extension:enterprise:2.0:User)

 
 
 

SCIM Attribute

 

SpeakUp Field

 

Type

 

Notes

 

employeeNumber

employeeNumber

string

Max 128 characters.

costCenter

costCentreId

option-list

Matched against existing values. Creates a new option-list item if not found.

department

departmentId

option-list

Matched against existing values. Creates a new option-list item if not found.

division

divisionId

option-list

Matched against existing values. Creates a new option-list item if not found.

organization

organizationId

option-list

Matched against existing values. Creates a new option-list item if not found.

manager

managerId

complex

value = user ID, $ref = User URL, displayName = manager's name.