Skip to main content
Which SCIM setup applies to you? These pages describe Living Security SCIM. Open the SCIM card in your settings. If the card shows Set up SCIM, or its Mode row says Native SCIM, these pages apply. If Mode says Current SCIM, your organization still uses the earlier SCIM setup. An admin can move it: see Move from the earlier SCIM setup. If the card says SCIM is set up and managed in the setup wizard, use SCIM Provisioning.
Living Security SCIM implements SCIM 2.0 (RFC 7643 and RFC 7644) and cursor pagination (RFC 9865). Identity providers (IdPs) use it. You do not need to call it yourself to provision people.

Base URL

https://api.<region>.livingsecurity.ai/scim/v2, where <region> is your organization’s data residency region, for example us-east-1, eu-west-1, ap-south-1 or ap-south-2. Copy it from the SCIM card. See Regional base URLs.
  • Request bodies use application/scim+json or application/json, in UTF-8.
  • Responses use application/scim+json; charset=utf-8.
  • Every response has an X-Request-Id header. Living Security creates it. Give it to support when you ask about a request.

Authentication

Send exactly one Authorization header. A connection accepts only the methods enabled for it. GET /ServiceProviderConfig lists them. Every refused credential gets the same 401 (LS-SCIM-1001) with WWW-Authenticate: Bearer realm="scim".

Endpoints

Every endpoint needs authentication, discovery included.
  • /Me returns 501 (LS-SCIM-1605). The SCIM client is a connection, not a person.
  • A write to a discovery endpoint returns 405. Another method that is not in the table returns 501.
  • changePassword is not supported. A password in a request is discarded.
  • Prefer: return=minimal on a PATCH returns 204 with no body. Other writes ignore it and return the resource.

ServiceProviderConfig

Schemas

  • User: userName is required and unique in your organization, without regard to case. externalId is case-sensitive and need not be unique: two users can have the same one. password is write-only. groups is read-only. Every core attribute is stored and returned.
  • Enterprise user: employeeNumber, costCenter, organization, division, department and manager (value is the manager’s SCIM id).
  • Living Security user: startDate (YYYY-MM-DD), location, and employmentType. Suggested employmentType values are full-time, part-time, contractor, intern, temporary and vendor. Any other text is accepted.
  • Group: displayName is required and need not be unique. externalId need not be unique. members hold user or group id values.
  • Other extensions: Living Security stores and returns any other extension your IdP sends, and adds it to /Schemas.
Every attribute, with its type, mutability, case rules and what it updates on the person, is in the SCIM attribute reference.

Filters

GET /Users?filter=..., GET /Groups?filter=... and the .search endpoints accept the full RFC 7644 filter language:
  • Operators: eq, ne, co, sw, ew, gt, ge, lt, le, pr, with and, or, not and parentheses.
  • Value paths, for example emails[type eq "work" and value co "@example.com"].
  • Extension paths, for example urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:department eq "Finance".
  • Attribute names are not case-sensitive. String comparison is not case-sensitive, except for attributes the schema marks caseExact, such as id and externalId.
  • co, sw and ew work on text only. Only eq and ne compare with null.
How an attribute name resolves:
  • A name that no schema has, such as a misspelled userNmae, returns 400 (LS-SCIM-1305).
  • A path in an extension your IdP has not sent yet matches nobody. The list returns totalResults: 0, so your IdP creates the user.
  • A name without a URN that exactly one extension has, such as employeeNumber, resolves to that extension. A name that two extensions have returns 400.
Limits: 4 KiB of filter text, 10 levels of nesting and 50 comparisons. Over a limit returns 400 (LS-SCIM-1304). An empty result is 200 with totalResults: 0 and Resources: [], never 404.

Sorting

  • sortBy takes any attribute. A multi-valued attribute sorts by its primary value, or its first value. A complex attribute sorts by its value sub-attribute.
  • sortOrder is ascending (default) or descending.
  • Ties sort by creation time, then id. Empty values sort last in ascending order.
  • An unusable sortBy or sortOrder returns 400 (LS-SCIM-1306).

Pagination

totalResults is always exact.

Index pagination

  • startIndex starts at 1 (the default). count defaults to 100. A count above 1,000 returns 1,000. count=0 returns only totalResults.
  • Index pagination is offset-based. If people change while you page, a page can repeat or skip a resource. Use a cursor for a full directory walk.

Cursor pagination

  1. Send an empty cursor (?cursor= or "cursor": "") with your first request. Do not send startIndex with cursor.
  2. Each response has nextCursor and, after the first page, previousCursor. Send nextCursor back as cursor to get the next page.
  3. The last page has no nextCursor.
  • A cursor is a position, not a snapshot. A walk without sortBy never skips or repeats a resource, even while resources change. A walk sorted by an attribute that changes during the walk can skip or repeat that resource, as RFC 9865 allows.
  • A cursor works only with the same filter and sort, on the same connection. Any other cursor returns 400 with scimType: invalidCursor (LS-SCIM-1303).
  • A cursor expires after 600 seconds. An expired cursor returns 400 with scimType: expiredCursor (LS-SCIM-1307). Start the walk again.
  • A cursor sorted by a long value can be too long for a URL. Use POST .../.search, which carries the cursor in the body.

PATCH

Send schemas: ["urn:ietf:params:scim:api:messages:2.0:PatchOp"] and an Operations list.
  • Operations: add, remove and replace, with or without path. Operation names are not case-sensitive, so Replace works.
  • Path forms: attribute, attribute.subAttribute, a full extension URN with an attribute, and value filters such as emails[type eq "work"].value or members[value eq "<id>"].
  • Extension attributes need the full URN in path, for example urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:employeeNumber. A bare employeeNumber returns 400 (LS-SCIM-1401).
  • The text values "True" and "False", in any case, are accepted for true and false.
  • A filter path that matches nothing returns 400 with scimType: noTarget. A change to a read-only or immutable attribute returns 400 with scimType: mutability.
  • Limits: 1,000 operations and 10,000 member values in one request (LS-SCIM-1406).
A successful PATCH returns 200 with the full resource and its new ETag.

ETags and versions

  • Every resource has meta.version, a weak ETag such as W/"3". GET, list, write and Bulk responses all carry it.
  • If-Match on PUT, PATCH and DELETE makes the write conditional. A mismatch returns 412 (LS-SCIM-1203). If-Match: * matches any existing resource.
  • A write without If-Match always applies. Living Security never returns 428.
  • If-None-Match on GET returns 304 when the version has not changed.

Bulk

POST /Bulk follows RFC 7644 section 3.7.
  • Up to 1,000 operations and 1 MiB per request. More operations return 413 (LS-SCIM-1114).
  • Operations: POST, PUT, PATCH and DELETE on /Users and /Groups. Each POST needs a bulkId.
  • bulkId:<id> references to resources created in the same request are resolved, including circular group membership. An unresolved reference returns 409 (LS-SCIM-1204) for that operation.
  • failOnErrors stops the request after that many failed operations.
  • An operation’s version works like If-Match.
  • Each operation runs on its own. A Bulk request is not all-or-nothing: the response gives each operation’s status, location, version and, on failure, an error body.

Limits

When Living Security pauses changes, writes return 503 with Retry-After (LS-SCIM-1602). Reads keep working.

Errors

Errors use the SCIM error schema. The detail ends with an LS-SCIM-nnnn code and a link to the code. See the SCIM error reference.