Skip to content

SCIM API reference

Jenz implements the parts of SCIM 2.0 that identity providers use to provision users. This page lists exactly what is supported, for configuring a provider other than Entra ID or writing your own client.

Basics

Setting Value
Base URL https://api.jenz.app/scim/v2
Resource Users
Authentication Authorization: Bearer <token> — one token per company, issued by Jenz
Request body JSON (application/scim+json or application/json)
Errors SCIM error schema, urn:ietf:params:scim:api:messages:2.0:Error

Not supported: Groups, DELETE (deactivate with active: false instead), bulk operations, /ServiceProviderConfig, /Schemas, /ResourceTypes, sorting, pagination, and listing users without a filter.

The User resource

{
  "schemas": [
    "urn:ietf:params:scim:schemas:core:2.0:User",
    "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"
  ],
  "id": "0c3a5f4e-6b1d-4c1e-9a77-2f1e8d2b9c10",
  "externalId": "E10442",
  "meta": {
    "resourceType": "User",
    "location": "https://api.jenz.app/scim/v2/Users/0c3a5f4e-6b1d-4c1e-9a77-2f1e8d2b9c10"
  },
  "userName": "ana.horvat@example.com",
  "name": {
    "givenName": "Ana",
    "familyName": "Horvat"
  },
  "title": "Product Manager",
  "emails": [
    { "value": "ana.horvat@example.com", "type": "work", "primary": true }
  ],
  "phoneNumbers": [
    { "value": "+385911234567", "type": "mobile" }
  ],
  "active": true,
  "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User": {
    "department": "Marketing"
  }
}
Attribute Read Write Notes
id ✓ Assigned by Jenz. Use it in /Users/{id}.
externalId ✓ ✓ Your identifier for the person, e.g. an employee number. Set on creation.
userName ✓ ✓ The person's e-mail address, which they sign in with. Always equal to the primary e-mail.
name.givenName, name.familyName ✓ ✓
title ✓ ✓ Job title. Defaults to Unknown on creation; an empty value is ignored.
emails ✓ ✓ Only the entry with "primary": true is used. Required on creation.
phoneNumbers ✓ ✓ Only "type": "mobile" is used. Present only when the user has one.
active ✓ ✓ false deactivates, true reactivates. Booleans and the strings "True" / "False" are both accepted.
…enterprise:2.0:User.department ✓ ✓ Department name. Created in Jenz if it does not exist. Present only when the user has one.

Any other attribute in a request is ignored.

Deactivated users are still readable. GET returns them with "active": false, as RFC 7644 recommends, so your provider can see that they exist and reactivate them later.

List users by filter

GET /scim/v2/Users?filter=userName eq "ana.horvat@example.com"

A filter is required, and exactly one of these is supported (attribute names and operators are case-insensitive):

Filter Matches
userName eq "<e-mail>" the user with that e-mail address
emails eq "<e-mail>" the same
externalId eq "<id>" the user with that external identifier

The answer is a ListResponse with zero or one user:

{
  "schemas": ["urn:ietf:params:scim:api:messages:2.0:ListResponse"],
  "totalResults": 1,
  "startIndex": 1,
  "itemsPerPage": 1,
  "Resources": [ { "id": "0c3a5f4e-…", "userName": "ana.horvat@example.com", "…": "…" } ]
}
Status When
200 Always when the filter is valid, also when nothing matches (totalResults: 0)
400 invalidFilter No filter, or a filter other than the three above

Get a user

GET /scim/v2/Users/{id}
Status When
200 The user, active or deactivated
404 No user with that id (empty body)

Create a user

POST /scim/v2/Users
Content-Type: application/scim+json
{
  "schemas": [
    "urn:ietf:params:scim:schemas:core:2.0:User",
    "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"
  ],
  "userName": "ana.horvat@example.com",
  "externalId": "E10442",
  "name": { "givenName": "Ana", "familyName": "Horvat" },
  "title": "Product Manager",
  "emails": [{ "value": "ana.horvat@example.com", "type": "work", "primary": true }],
  "phoneNumbers": [{ "value": "+385911234567", "type": "mobile" }],
  "active": true,
  "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User": { "department": "Marketing" }
}

What Jenz does, in order:

  1. Takes the e-mail from the emails entry marked "primary": true. Without one: 400.
  2. Looks for an existing user with that e-mail, or with that externalId:
    • active → 409 uniqueness, nothing changes;
    • deactivated → that user is reactivated and updated from the request, 201;
    • none → a new user is created, 201.
  3. Applies the mobile number if it is valid and no other Jenz account uses it; otherwise skips it and still creates the user.

The response body is the created or reactivated user.

Status When
201 Created, or reactivated
400 Invalid JSON, or no primary e-mail
409 uniqueness An active user already has that e-mail or externalId

Update a user

PATCH /scim/v2/Users/{id}
Content-Type: application/scim+json

A standard SCIM PatchOp. Jenz applies add and replace operations; remove operations are ignored.

{
  "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
  "Operations": [
    { "op": "replace", "path": "title", "value": "Head of Marketing" },
    { "op": "replace", "path": "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:department", "value": "Marketing" },
    { "op": "replace", "path": "active", "value": false }
  ]
}

Supported path values (case-insensitive):

Path Effect
active false deactivates the user, true reactivates them
userName Changes the e-mail address
emails[type eq "work"].value Changes the e-mail address
name.givenName First name
name.familyName Last name
title Job title (an empty value is ignored)
phoneNumbers[type eq "mobile"].value Mobile number (skipped if invalid or used by another account)
urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:department Department, created if it does not exist

An operation without a path may carry an object of attributes as its value, the same shape as in Create a user:

{
  "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
  "Operations": [
    { "op": "replace", "value": { "name": { "givenName": "Ana", "familyName": "Kovač" }, "active": true } }
  ]
}

Paths other than those listed are ignored. The response body is the updated user.

Status When
200 Updated
400 Invalid JSON
404 No user with that id
409 uniqueness The new e-mail address belongs to another user

Errors

Errors use the SCIM error schema:

{
  "schemas": ["urn:ietf:params:scim:api:messages:2.0:Error"],
  "status": "409",
  "scimType": "uniqueness",
  "detail": "User with email \"ana.horvat@example.com\" already exists."
}
Status Meaning
400 Malformed request; scimType is invalidFilter for an unsupported filter
401 Missing, wrong or rotated token
404 Unknown user id
409 uniqueness: the e-mail or externalId is taken by another user

Rely on the HTTP status rather than the body for 401: depending on where the token is rejected, the body may not follow the SCIM error schema.

Example with curl

TOKEN='…'   # from your secret manager

curl -s https://api.jenz.app/scim/v2/Users \
  -G --data-urlencode 'filter=userName eq "ana.horvat@example.com"' \
  -H "Authorization: Bearer $TOKEN"