Skip to main content
Version: 1.0.0

SCIM Service API

SCIM 2.0 provisioning service for Inspectorio products.

It is based on the SCIM 2.0 protocol (RFC 7644) and schema (RFC 7643) specifications.

This API enables Identity Providers (e.g. Microsoft Entra ID; also compatible with any SCIM 2.0 client) to automate user provisioning and deprovisioning across RSC, QRM, and Digital Assets Management.

If you are configuring Microsoft Entra ID, follow the step-by-step Entra ID SCIM Configuration Guide β€” this document is the reference for the underlying API.

Getting Started
  1. Authenticate β€” Include your Secret Token in the Authorization header of every request as an HTTP Bearer token: Authorization: Bearer <your-secret-token>
  2. Discover roles β€” GET /v2/{product}/UserOrganizationRoles to retrieve available role IDs for your product. Replace {product} with your product path prefix: rise (RSC), sight (QRM), or docuflow (Digital Assets Management). Role IDs are environment-specific β€” always call GET /UserOrganizationRoles again when you move between pre-production and production. Hardcoding role IDs across environments is unsupported.
  3. Create users β€” POST /v2/{product}/Users with a JSON body. The minimum payload accepted by this service is { userName, roles } β€” displayName is optional but strongly recommended (when omitted the user record is created with empty first/last name fields); other SCIM attributes are accepted on input but ignored. See the example below.
  4. Manage users β€” GET (list/filter), PATCH (update attributes), DELETE (remove/deactivate).
  5. Minimal integration β€” Most Identity Providers only need POST (idempotent upsert; creates or updates) and DELETE (remove/deactivate per product). PUT and PATCH are supported for finer-grained control but are not required for a complete provisioning lifecycle. See Recommended minimal integration below.

Example body for step 3 (POST /v2/{product}/Users):

{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"userName": "[email protected]",
"displayName": "Jane Doe",
"roles": [{ "value": "<role-id-from-step-2>" }]
}
Authentication

Entra ID admins: follow the step-by-step Entra ID SCIM Configuration Guide (formerly Azure AD).

SCIM endpoints require an Inspectorio Secret Token in the Authorization header, sent as an HTTP Bearer token. Secret Tokens are tenant-specific and issued by your Inspectorio Account Manager or Customer Success Manager (CSM) during onboarding. Your token is scoped to your tenant ecosystem β€” the Inspectorio organization(s) your company has been set up with; all user listings and mutations operate within that scope. Example:

Authorization: Bearer <your-secret-token>

Secret Tokens do not expire β€” the token can be used indefinitely unless there is a specific need to renew it. Renewal is on-demand only; contact your CSM when you need to rotate.

Tenant URL & product endpoints

Tenant URL

Configure your Identity Provider with the SCIM base URL pattern:

https://scim.{env}.inspectorio.com/v2/{product}/

Where {env} is pre for pre-production or omitted (e.g. scim.inspectorio.com) for production, and {product} is rise, sight, or docuflow. The base URL ends with /v2/{product}/ β€” a trailing slash is required. The service does not normalize URLs: joining a trailing-slash base with a leading-slash path produces a double slash (/v2/sight//Users) and returns 404, exactly like a missing separator (/v2/sightUsers) β€” append resource names without a leading slash.

Microsoft Entra ID only: paste the URL above with ?aadOptscim062020 appended into the Tenant URL field in Entra ID Provisioning β€” that query parameter opts Entra ID into its compliant SCIM 2.0 behavior. Other identity providers should use the base URL without the query string. Because the Tenant URL is product-specific, create one Entra Enterprise Application per Inspectorio product you provision to.

Product endpoints

Each product has its own set of SCIM resources under a dedicated path prefix:

ProductPath prefixUser ID formatRole ID format
RSC/rise/UUIDUUID
QRM/sight/Integer (passed as a JSON string)Integer (passed as a JSON string)
Digital Assets Management/docuflow/UUIDUUID

Your Secret Token determines which products you have access to. Calling a product endpoint that is not configured for your tenant returns 403 with detail Tenant is not configured for {Product}.

Note (product names in error messages): error messages returned by the API refer to products by their API names β€” Rise (RSC), Sight (QRM), Docuflow (Digital Assets Management). For example, the 403 detail reads Tenant is not configured for Docuflow.

Only the endpoints listed in this document are supported: GET /v2/Me and POST /v2/Bulk return 501, and write verbs on /UserOrganizationRoles return an error (the role catalog is read-only). POST /v2/{product}/Users/.search (RFC 7644 Β§3.4.3) is available as a POST alternative to GET with a filter β€” see its endpoint documentation for caveats.

Content types

Responses are always served as application/scim+json per RFC 7644 Β§3.1. Request bodies with Content-Type: application/scim+json (recommended) and application/json are both accepted and parsed identically. Any other content type (e.g. text/plain) leaves the body unparsed: write requests return 400 with a generic error (Cannot read properties of undefined (reading 'roles')). For POST /Users/.search the consequence is different and worth knowing β€” see the .search endpoint documentation.

Users created via this API

Users provisioned through SCIM are SSO-only β€” they can authenticate only via your organization's configured SSO method (e.g. Microsoft Entra ID) and cannot log in with username/password: no password credential is ever created for them, and a password login attempt returns a generic 400 Invalid email or password (indistinguishable from a wrong password).

On production, a successful POST /Users may send a first-access email to the user (the SCIM create auto-accepts the invitation on all three products β€” the email is a notification only; no click is required). There is no SCIM-side API to check delivery status or re-send it. If a user reports they did not receive it, the admin should re-send it through the product UI (RSC, QRM, or Digital Assets Management web app).

Existing password-login users

If you roll SCIM out to users who already have a manual password login with the same email: on RSC and Digital Assets Management, a provisioning update that targets such a pre-existing password-login user removes that account and re-creates it as an SSO-only account (the displayName from the request is applied, and the user receives a new id). Password-only users do not appear in GET /Users, so you will not see the collision coming β€” plan the migration accordingly.

Recommended minimal integration

Most Identity Providers only need to implement two of the eight verbs:

  • POST /v2/{product}/Users β€” idempotent upsert. Creates the user if they do not exist; updates roles if they do. Returns 201 in both cases. POST always results in active: true β€” the request body's active value is ignored on POST, and on QRM and Digital Assets Management a POST on an INACTIVE user reactivates them (even if the body says active: false). Use PATCH/PUT/DELETE to deactivate.
  • DELETE /v2/{product}/Users/{id} β€” removes or deactivates the user. Exact semantics vary per product (see Status Mapping below).

PUT and PATCH are supported for finer-grained control (e.g. updating roles without touching active) but are not required for a complete provisioning lifecycle.

Note (lookup before PUT/DELETE): Use GET /v2/{product}/Users?filter=userName eq "[email protected]" (URL-encoded) to recover a user's id before a PUT or DELETE. See SCIM Filter Syntax below for the encoding rules.

SCIM Filter Syntax

Use the filter query parameter to search resources. Syntax: <attribute> <operator> <value>

URL encoding

Filter values are URL query-string parameters and must be URL-encoded. Common substitutions:

RawEncoded
space%20 (or +)
" (quote)%22
@ (at sign)%40

Example. To find a user by email, the raw filter:

filter=userName eq "[email protected]"

becomes the encoded query string:

?filter=userName%20eq%20%22user%40example.com%22

A worked curl command:

curl -H 'Authorization: Bearer <token>' \
'https://scim.pre.inspectorio.com/v2/sight/Users?filter=userName%20eq%20%22user%40example.com%22'

Note: A filter with a syntax error (e.g. an unterminated quote or a truncated operator) returns 400 with scimType: invalidFilter and a parse message. A filter consisting of an attribute with no operator at all (e.g. ?filter=userName) currently returns 500 with a generic Cannot read properties of undefined (reading 'toLowerCase') message β€” use userName pr to test for presence. Encode all special characters anyway.

Supported Operators

OperatorDescriptionExample
eqEqualuserName eq "[email protected]"
neNot equaluserName ne "[email protected]"
coContainsdisplayName co "Jane"
swStarts withuserName sw "jane"
ewEnds withuserName ew "@example.com"
gtGreater thanuserName gt "j"
geGreater than or equaluserName ge "j"
ltLess thanuserName lt "z"
leLess than or equaluserName le "z"
prPresent (has any value)userName pr

Logical operators and, or, and not are supported per RFC 7644 Β§3.4.2.2. Example: userName sw "jane" and active eq true (use lowercase values in compound filters β€” see the case-sensitivity note below).

Filterable Attributes

EndpointFilterable attributes
/{product}/UsersuserName, displayName, active, id
/{product}/UserOrganizationRolesdisplay, id

Note (unsupported attributes): Filtering on name.givenName, name.familyName, or emails[…] is accepted by the parser but always returns zero matches β€” those fields are not persisted by this service.

Note (string case-sensitivity): Always send lowercase filter values. The rules:

  • Simple filters (a single comparison): the value is lowercased before matching, so userName email lookups are case-insensitive. Caveat: only the filter value is lowercased β€” stored displayName values with mixed case may not match.
  • Compound filters (and/or/not): values are compared verbatim. A mixed-case value under and/or silently matches nothing; under not it matches everyone (the inner comparison fails for every user, so the negation includes them all).
  • UserOrganizationRoles filters: values are never lowercased.

Note (boolean filters): Use unquoted boolean literals for active: active eq true, active eq false. Quoted strings like active eq "true" are compared against the boolean attribute as strings and never match.


Attribute Mapping Reference​

This section documents how SCIM 2.0 attributes from the Identity Provider (e.g. Microsoft Entra ID) are mapped to each downstream product: RSC, QRM, and Digital Assets Management.

Microsoft Entra ID role mapping (Entra ID-specific)

This section applies only to Microsoft Entra ID setups. In Entra ID, each Enterprise Application defines App roles, each with a Display name and a Value. To provision a user with a given product role, the App role Value must equal the internal product role ID returned by GET /{product}/UserOrganizationRoles.

Entra ID App role fieldMaps to SCIMSource of truth
Display nameroles[].displayCosmetic only β€” overwritten on read by the product's role name
Valueroles[].valueMust equal the role id returned by GET /{product}/UserOrganizationRoles

For QRM, role IDs are integers but the SCIM schema requires them to be sent as JSON strings β€” e.g. configure Entra App role Value as "4", not 4.

Microsoft Entra ID Attribute Mapping (Entra ID-specific)

The full Entra ID setup walkthrough is in the Entra ID SCIM Configuration Guide. The four attribute mappings required for SCIM provisioning are:

Target (SCIM)Entra ID expressionNotesRequiredMulti-value
userNameuserPrincipalNameUser's email (primary identifier)yesno
activeNot([IsSoftDeleted])Deactivate on Entra ID soft-deleteyesno
displayNamedisplayNameFull name (split into first/last)yesno
rolesAppRoleAssignmentsComplex([appRoleAssignments])All assigned app roles for the useryesyes

Remove all other attribute rows from the Entra ID provisioning mapping. Mark userName, active, displayName as Required in Entra ID's advanced attribute settings; the roles attribute is added manually with type String, Required, Multi-Value.

App role Value fields in Entra ID must equal the role id returned by GET /{product}/UserOrganizationRoles for the target environment. For QRM (integer IDs), enter the role ID as a string β€” e.g. "4", not 4. App role Values are environment-specific: use a separate Enterprise Application per environment (or update every App role Value) when moving from pre-production to production.

Note (Digital Assets Management): assign each user exactly one App role in the Enterprise Application β€” multiple assignments provision multiple roles, and the request is rejected with 400.

Note (name changes): name changes made in your IdP after creation do not propagate β€” the update succeeds with no effect on the stored name. To force a name update, delete and re-create the user (the re-created user receives a new id).

User Attribute Mapping
SCIM AttributeDescriptionRSCQRMDigital Assets Management
userNameUser email (primary identifier)email (lowercase, trimmed)email (lowercase, trimmed)email (lowercase, trimmed)
displayNameFull name of the userSplit into firstName + lastNameSplit into first_name + last_nameSplit into firstName + lastName
activeWhether the user is activetrue β†’ ACTIVE; false β†’ see Status Mappingtrue β†’ ACTIVE; false β†’ see Status Mappingtrue β†’ ACTIVE; false β†’ see Status Mapping
roles[].valueRole identifierUUID string (multiple roles supported)Integer-as-string (multiple roles supported)UUID string (exactly one role required)
roles[].displayRole display name (input)Same for all products β€” see note belowSame for all products β€” see note belowSame for all products β€” see note below
emails[].valueEmail addressesNot used (uses userName)Not used (uses userName)Not used (uses userName)
name.givenNameFirst nameNot used (uses displayName)Not used (uses displayName)Not used (uses displayName)
name.familyNameLast nameNot used (uses displayName)Not used (uses displayName)Not used (uses displayName)
idSCIM resource ID (read-only)Product user UUIDProduct user ID (integer-as-string)Product user UUID

Note (roles[].display): the input value is cosmetic β€” on responses, display is overwritten with the product's role name for the role ID. Role IDs the product no longer recognizes are omitted from write responses.

Data Transformations

Inspectorio applies the following normalizations automatically β€” no customer action is required.

TransformationRuleExample
Email normalizationConverted to lowercase and trimmed" [email protected] " β†’ "[email protected]"
Display name normalizationLeading/trailing whitespace trimmed; consecutive internal spaces collapsed to one"Jane van Doe" β†’ "Jane van Doe"
Display name parsingSplit on first space; if single word, used for both first and last name"Jane Doe" β†’ firstName: "Jane", lastName: "Doe"
Multi-word last names are preserved"Jane van Doe" β†’ firstName: "Jane", lastName: "van Doe"
Single name is duplicated"Jane" β†’ firstName: "Jane", lastName: "Jane"
Role add→replace rewriteSome Entra ID provisioning flows emit op: "add" on the roles path. Inspectorio rewrites those to replace to keep the operation idempotent.op: "add", path: "roles" → op: "replace", path: "roles"
Boolean-path PATCH rewriteSome Entra ID provisioning flows emit PATCH ops where path is the literal string "true" or "false". Inspectorio rewrites those to path: "active" with the corresponding boolean value.op: "replace", path: "false" β†’ op: "replace", path: "active", value: false
Status Mapping

How active translates into customer-observable behavior on each product:

Reversible deactivation (QRM, Digital Assets Management Admin/User):

PATCH /v2/{product}/Users/{id}
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
"Operations": [{ "op": "replace", "path": "active", "value": false }]
}

To reactivate, send the same payload with "value": true. The user remains in GET /Users responses with "active": false.

Permanent removal (RSC always; QRM via DELETE; Digital Assets Management Visitor):

DELETE /v2/{product}/Users/{id}
SCIM activeRSCQRMDigital Assets Management
trueACTIVE β€” appears in GET /UsersACTIVE β€” appears in GET /UsersACTIVE β€” appears in GET /Users
falsePermanently removed β€” see RSC notesDeactivated (INACTIVE) β€” see QRM notesVisitor removed; Admin/User deactivated β€” see notes
(on create)ACTIVE (invitation auto-accepted) β€” see RSC notesACTIVE (auto-accepted)ACTIVE (auto-accepted)
(reactivation)Not supported β€” see RSC notesPATCH active=true or POST upsert β€” see QRM notesPATCH active=true or POST upsert β€” see notes

RSC notes:

  • active=false permanently deletes the user from the organization. The PATCH response returns 200 echoing active: false, but the id is dead immediately β€” a subsequent GET /Users/{id} returns 404 and the user is gone from the list.
  • On a not-yet-activated (PENDING) invitee, PATCH active=false returns 404 and removes nothing β€” use HTTP DELETE to remove a pending invitation.
  • On create, the invitation is issued and auto-accepted within the same request, so the user is ACTIVE immediately in both the list and by-id GET. If auto-activation fails, the invitation remains PENDING and is invisible to GET (list and by-id); it can still be removed via DELETE /Users/{id}.
  • Reactivation is not supported: PATCH active=true on a removed user returns 404. Re-create the user via POST β€” the re-created user receives a new id (the old id never resolves again).

QRM notes:

  • PATCH active=false deactivates the user (INACTIVE); they remain in GET /Users with active: false and can be reactivated.
  • Session invalidation on deactivation follows the product's own behavior. To guarantee immediate session revocation, use HTTP DELETE β€” it revokes the user's active sessions and removes the user permanently (no longer queryable).
  • Reactivation may fail with 409 if the organization user quota is exceeded.

Digital Assets Management notes:

  • Visitor semantics apply to the role whose display name is exactly Visitor (case-sensitive). active=false or HTTP DELETE on a Visitor permanently removes them.
  • Admin/User accounts deactivate to INACTIVE and remain in GET /Users with active: false for audit and reactivation.
  • HTTP DELETE on an already-INACTIVE Admin/User is an idempotent no-op (204).
  • Quota errors on reactivation currently surface as 500 (asymmetric with QRM's 409).

Note (role updates): Role assignment via PATCH/PUT updates the user's role in the product. After a role change, the user must sign out and back in before newly granted areas of the product become visible; some products may require additional setup steps outside SCIM. Inspectorio cannot guarantee a role update alone grants immediate access.

Role Handling Per Product
AspectRSCQRMDigital Assets Management
Multiple rolesSupportedSupportedExactly one role per user is required for Digital Assets Management
Role ID formatUUID stringInteger, sent as a JSON string (e.g. "4")UUID string
Visitor downgradeβ€” (Visitor role only exists in Digital Assets Management)β€” (Visitor role only exists in Digital Assets Management)Not allowed (cannot downgrade an Admin/User to Visitor)
Empty rolesAt least one role requiredAt least one role requiredExactly one role required

Note (identifying the Visitor role): Visitor semantics apply to the Digital Assets Management catalog role whose display name is exactly Visitor (case-sensitive); a differently named role is treated as a regular Admin/User role.

Note: A POST /Users without at least one role returns 400 with a message containing the word "role". Some IGA systems swallow this 400 and report "no invite sent" β€” make sure your IGA surfaces the SCIM error.

Authentication​

Security Scheme Type:

http

HTTP Authorization Scheme:

bearer