For AI agents: a documentation index is available at the root level at /llms.txt and /llms-full.txt. Append /llms.txt to any URL for a page-level index, or .md for the markdown version of any page.
Sign inTry it free
DocsGuidesSDKsIntegrationsAPI docsTutorialsFlagship blog
DocsGuidesSDKsIntegrationsAPI docsTutorialsFlagship blog
  • Get started
    • Overview
    • Onboarding
    • Get started
    • Launch Insights
    • LaunchDarkly architecture
    • LaunchDarkly vocabulary
  • AgentControl
    • AgentControl
    • Manage AgentControl
  • Feature flags
    • Create flags
    • Target with flags
    • Flag templates
    • Manage flags
    • Code references
    • Contexts
    • Segments
  • Releases
    • Releasing features with LaunchDarkly
    • Release policies
    • Percentage rollouts
    • Progressive rollouts
    • Guarded rollouts
    • Feature monitoring
    • Release pipelines
    • Engineering insights
    • Release management tools
    • Applications and app versions
    • Change history
    • Restoring previous flag versions
  • Observability
    • Observability
    • Session replay
    • Error monitoring
    • Logs
    • Traces
    • Observability metrics
    • Product analytics events
    • LLM observability
    • Alerts
    • Dashboards
    • Service map
    • Vega for auto-remediation
    • Observability MCP server
    • Search specification
    • Observability settings
    • Observability integrations
  • Experimentation
    • Experimentation
    • Experiment metric types
    • Experiment configuration
    • Managing experiments
    • Analyzing experiments
    • Multi-armed bandits
    • Holdouts
  • Metrics and events
    • Metrics in LaunchDarkly
    • Creating metrics
    • Metric groups
    • Events
    • Autogenerated metrics
  • Warehouse native
    • Warehouse native metrics
    • Setting up external warehouses
    • Creating experiments using warehouse native metrics
  • Infrastructure
    • Connect apps and services to LaunchDarkly
    • LaunchDarkly in China and Pakistan
    • LaunchDarkly in the European Union (EU)
    • LaunchDarkly in federal environments
    • Public IP list
  • Your account
    • Projects
    • Views
    • Environments
    • Tags
    • Teams
    • Members
    • Roles
    • Account security
      • Single sign-on
        • Configure SAML SSO
        • Enable SCIM provisioning
          • Using the SCIM API
        • Enable SSO
        • Disable SSO
        • Change SSO providers
        • Google OAuth
        • GitHub OAuth
      • API access tokens
      • Multi-factor authentication
      • Domain verification
      • IP allowlist
      • Managing sessions
      • Organization access settings
      • Organization announcements
      • Support options
      • Resetting your password
    • Feature previews
    • Billing and usage
    • Changelog
Sign inTry it free
LogoLogo
On this page
  • Authentication
  • API endpoints
  • User endpoints
  • Group endpoints
  • Schema endpoints
  • User schema and attributes
  • Required fields
  • Optional and behavioral fields
  • LaunchDarkly extension attributes (roles)
  • Read-only fields in responses
  • Example user requests
  • Create user (POST)
  • Update user (PUT)
  • Update user (PATCH)
  • Get user (GET)
  • Query users (GET)
  • Search users (POST)
  • Delete user (DELETE)
  • Group schema and attributes
  • Group fields
  • Error responses
  • Common error messages
  • API constraints and troubleshooting
  • Owner restrictions
  • Deactivated users
  • Role keys
  • Email uniqueness
  • Field validation
  • Okta compatibility
  • Extension schema declaration
Your accountAccount securitySingle sign-onEnable SCIM provisioning

Using the SCIM API

Was this page helpful?
Previous

Enable SSO

Next
Built with

This topic explains how to use the System for Cross-domain Identity Management (SCIM) API to work with users, roles, and teams in your SSO-enabled LaunchDarkly account.

The SCIM API enables user provisioning of account members from identity providers (IdPs). SCIM enables IdPs such as Okta, OneLogin, or Entra ID to tell LaunchDarkly which users should or should not have an account, and optionally determine what level of access users have in LaunchDarkly.

SCIM uses web (REST) APIs to exchange data formatted in JSON, with a standard schema that works with two resource types: User and Group. The LaunchDarkly SCIM API maps the Group resource to LaunchDarkly teams. Group-based team sync is currently only available through the Okta integration. We provide an extension schema to work with LaunchDarkly roles. To learn more, read Teams and Roles.

You cannot manage teams using the UI after enabling SCIM

If you configure SCIM to provision resources from identity providers, you can no longer manage teams using the LaunchDarkly user interface.

Authentication

The SCIM API is only supported for the OAuth2 authorization type. Not all supported third-party providers support user provisioning through SCIM. To learn more about how LaunchDarkly treats users imported from the IdP, read Default initial role.

All SCIM endpoints require OAuth2 authentication with the scim scope. Regular personal access tokens will not work. You must use a SCIM-enabled OAuth client.

The following information is generally needed to configure SCIM in your IdP. The actual names for these fields may vary by IdP:

  • SCIM Base URI: https://app.launchdarkly.com/trust/scim/v2
  • Authorization method: oauth2
  • Authorization URI: https://app.launchdarkly.com/trust/oauth/authorize
  • Access token URI: https://app.launchdarkly.com/trust/oauth/token
  • Unique Identifier field for account members: userName

If you are using the LaunchDarkly app from the Okta or OneLogin catalog, authentication is handled automatically during the setup wizard.

For Entra ID or any other provider you configure manually, you will also need a Client ID and Client Secret. Start a Support ticket and we will generate these for you.

You can also use the REST API: OAuth2 Clients

API endpoints

This section describes all endpoints provided with the SCIM API.

All SCIM endpoints are prefixed with the base URL: https://app.launchdarkly.com/trust/scim/v2

User endpoints

MethodEndpointDescription
POST/UsersCreate a new user (member)
GET/Users/{id}Get a user by ID
GET/UsersQuery/list users (supports filtering)
POST/Users/.searchSearch users (POST query) - accepts filter, startIndex, and count in request body instead of query parameters
PUT/Users/{id}Full update of a user (requires a complete user object)
PATCH/Users/{id}Partial update of a user
DELETE/Users/{id}Delete (deactivate) a user

Group endpoints

Groups in LaunchDarkly map to teams.

Group endpoints are only available for the Okta IdP

The SCIM Group endpoints are used by the Okta integration to power team sync. They are not intended for direct API calls or custom SCIM integrations. If you use a different IdP, you cannot use these endpoints to manage teams. To learn more about team sync, read Team sync with SCIM.

MethodEndpointDescription
POST/GroupsCreate a new team
GET/Groups/{id}Get a team by ID
GET/GroupsList all teams (supports filtering and pagination)
PUT/Groups/{id}Full update of a team
PATCH/Groups/{id}Add or remove members from a team
DELETE/Groups/{id}Delete a team

Schema endpoints

MethodEndpointDescription
GET/SchemasGet SCIM schema definitions (core and extension schemas)

User schema and attributes

LaunchDarkly uses the standard SCIM 2.0 user schema (urn:ietf:params:scim:schemas:core:2.0:User) and supports a custom extension schema (urn:ietf:params:scim:schemas:extension:launchdarkly:2.0:User) for LaunchDarkly-specific permissions.

Required fields

FieldTypeDescription
emailsArrayAt least one email is required. The value must be a valid email address and must be unique within the account. Each email object can include:
- value (string, required): Email address
- primary (boolean): Whether this is the primary email
- type (string): Email type (for example, “work”)
Email (not userName) is required

While the SCIM 2.0 standard typically requires userName, LaunchDarkly’s implementation requires emails instead. The userName field is optional and defaults to the email address if not provided. Most IdPs should map their unique identifier to the userName field for proper user matching.

Optional and behavioral fields

FieldTypeDescription
userNameStringRecommended. While SCIM standards typically require this, LaunchDarkly relies on email as the primary identifier. If userName is omitted, the API defaults it to the email address. The value is in lowercase and trimmed.
activeBooleanDefault: true. Set to false to deactivate the user (revoke access).
externalIdStringIdentifier from the IdP. Used to map users between systems.
nameObjectA complex object containing:
- givenName (string, max 256 chars): First name
- familyName (string, max 256 chars): Last name

LaunchDarkly extension attributes (roles)

LaunchDarkly allows you to define roles using either the standard extension namespace or root-level attributes for convenience.

FieldTypeDescription
roleStringThe built-in role: "reader", "writer", "admin", or "noAccess". Default: "reader" (or the SAML default role if configured). Cannot be "owner" on create/update.
customRoleStringA comma-separated list of custom role keys (for example, "qa-team,release-mgr").
customRolesArrayArrayAn array of custom role keys (for example, ["qa-team", "release-mgr"]).

Root-level fields, such as role, take precedence over fields that are nested in the extension namespace. If both customRolesArray and customRole are provided, customRolesArray takes precedence.

You can also use the extension namespace format, which is useful for IdPs like Azure Entra ID:

1{
2 "schemas": [
3 "urn:ietf:params:scim:schemas:core:2.0:User",
4 "urn:ietf:params:scim:schemas:extension:launchdarkly:2.0:User"
5 ],
6 "emails": [{"value": "user@example.com"}],
7 "urn:ietf:params:scim:schemas:extension:launchdarkly:2.0:User": {
8 "role": "admin",
9 "customRole": "custom-role-1"
10 }
11}

You cannot create new custom attributes using the SCIM API, but you can set the role and customRole attributes for SCIM users. For SAML-based SSO, LaunchDarkly supports mapping only the role, customRole, and teamKey attributes.

To learn more about these attributes, read Roles.

For an in-depth guide on how to use custom roles with IdPs, read Creating roles.

Read-only fields in responses

The following fields are automatically generated by LaunchDarkly and cannot be set or modified:

FieldTypeDescription
idStringThe LaunchDarkly member ID, used for updates and deletes. This ID is permanent, and does not change even if the member’s email address is updated.
schemasArrayAn Array of SCIM schema identifiers
metaObjectA Metadata object containing:
- resourceType: Resource type (for example, “User”)
- created: Creation timestamp (Unix milliseconds)
- lastModified: Last modification timestamp (Unix milliseconds)
- location: URL to fetch this resource
- version: Version number

Example user requests

Create user (POST)

Endpoint: POST /scim/v2/Users

Minimal request:

1{
2 "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
3 "emails": [
4 {
5 "value": "alice@example.com",
6 "primary": true
7 }
8 ],
9 "name": {
10 "givenName": "Alice",
11 "familyName": "Smith"
12 }
13}

Request with custom roles (root level):

1{
2 "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
3 "emails": [{"value": "bob@example.com"}],
4 "role": "reader",
5 "customRolesArray": ["approver", "beta-tester"]
6}

Response: 201 Created with the created user object including the LaunchDarkly id field.

Update user (PUT)

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

PUT requires the complete user object. All fields should be included.

1{
2 "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
3 "id": "507f1f77bcf86cd799439011",
4 "externalId": "external-123",
5 "userName": "jane",
6 "name": {
7 "givenName": "Jane",
8 "familyName": "Smith"
9 },
10 "emails": [
11 {
12 "value": "jane.smith@example.com",
13 "primary": true,
14 "type": "work"
15 }
16 ],
17 "active": true,
18 "role": "admin",
19 "customRole": "custom-role-1"
20}

Response: 200 OK

Update user (PATCH)

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

LaunchDarkly supports both SCIM PATCH format and JSON Patch (RFC 6902) for partial updates.

SCIM patch format:

1{
2 "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
3 "Operations": [
4 {
5 "op": "replace",
6 "path": "/active",
7 "value": false
8 }
9 ]
10}

Update custom roles:

1{
2 "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
3 "Operations": [
4 {
5 "op": "replace",
6 "path": "/customRolesArray",
7 "value": ["new-role-key"]
8 }
9 ]
10}

JSON patch format (alternative):

1[
2 {
3 "op": "replace",
4 "path": "/role",
5 "value": "writer"
6 },
7 {
8 "op": "replace",
9 "path": "/emails/0/value",
10 "value": "newemail@example.com"
11 }
12]

Supported operations: add, remove, replace

Get user (GET)

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

Response: 200 OK with complete user object.

Complete response example:

1{
2 "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
3 "id": "507f1f77bcf86cd799439011",
4 "externalId": "external-123",
5 "userName": "user@example.com",
6 "name": {
7 "givenName": "John",
8 "familyName": "Doe"
9 },
10 "emails": [
11 {
12 "value": "user@example.com",
13 "primary": true,
14 "type": "work"
15 }
16 ],
17 "active": true,
18 "role": "reader",
19 "customRole": "custom-role-1,custom-role-2",
20 "customRolesArray": ["custom-role-1", "custom-role-2"],
21 "urn:ietf:params:scim:schemas:extension:launchdarkly:2.0:User": {
22 "role": "reader",
23 "customRole": "custom-role-1,custom-role-2"
24 },
25 "meta": {
26 "resourceType": "User",
27 "created": 1234567890000,
28 "lastModified": 1234567890000,
29 "location": "/scim/v2/Users/507f1f77bcf86cd799439011",
30 "version": "1"
31 }
32}

Query users (GET)

Endpoint: GET /scim/v2/Users

Query parameters:

  • filter: SCIM filter expression (for example, userName eq "user@example.com")
  • startIndex: 1-based starting index for pagination
  • count: Number of results per page

Examples:

GET /scim/v2/Users?filter=userName eq "user@example.com"
GET /scim/v2/Users?startIndex=1&count=100

Response:

1{
2 "schemas": ["urn:ietf:params:scim:api:messages:2.0:ListResponse"],
3 "totalResults": 1,
4 "itemsPerPage": 100,
5 "startIndex": 1,
6 "Resources": [
7 {
8 "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
9 "id": "507f1f77bcf86cd799439011",
10 "userName": "user@example.com",
11 "emails": [{"value": "user@example.com", "primary": true}],
12 "active": true,
13 "role": "reader"
14 }
15 ]
16}

Search users (POST)

Endpoint: POST /scim/v2/Users/.search

This is an alternative to GET /scim/v2/Users that accepts filter parameters in the request body.

Request:

1{
2 "filter": "userName eq \"user@example.com\"",
3 "startIndex": 1,
4 "count": 10
5}

Response: Same format as GET /scim/v2/Users (ListResponse)

Delete user (DELETE)

Endpoint: DELETE /scim/v2/Users/{id}

Response: 204 No Content (or 200 OK with empty body)

Note: Deleting a user deactivates them and removes them from the account and all teams. Cannot delete an owner.

Group schema and attributes

Groups in LaunchDarkly map to teams. The Group endpoints are used by the Okta integration to sync IdP groups to LaunchDarkly teams. They are not intended for direct API calls or custom SCIM integrations.

To manage teams through Okta, enable team sync with SCIM in LaunchDarkly, and then manage teams through Group Push in Okta. To learn more, read Use Okta to manage LaunchDarkly teams with SCIM.

Group fields

FieldTypeDescription
displayNameStringRequired. The name of the team.
externalIdStringOptional. External identifier from the IdP.
membersArrayOptional. Array of member objects, each containing:
- value (string): Member ID (LaunchDarkly member ID)
- display (string): Member email address

Error responses

All errors follow the SCIM error format:

1{
2 "schemas": ["urn:ietf:params:scim:api:messages:2.0:Error"],
3 "detail": "Error message here",
4 "status": 400
5}

Common error messages

ErrorStatus codeDescription
member already exists409 ConflictEmail already exists in account
member not found404 Not FoundUser ID does not exist
Invalid email address400 Bad RequestEmail format is invalid
'role-name' is not a valid primary role400 Bad RequestInvalid role value
Cannot create an owner400 Bad RequestCannot create users with owner role
Cannot deactivate an owner400 Bad RequestCannot deactivate account owner
Unknown custom role 'role-key'400 Bad RequestCustom role doesn’t exist
Cannot change properties on deactivated members other than 'active'400 Bad RequestCannot update deactivated users
Name length must not exceed 256 characters400 Bad RequestName field too long

To learn more about how to remediate SCIM assertion consumer errors, read SSO SCIM Error Messages.

API constraints and troubleshooting

Owner restrictions

  • You cannot create users with the "owner" role (returns 400 error: “Cannot create an owner”)
  • Any attempt to update an existing owner’s role using SCIM is silently ignored (no error is returned)
  • You cannot deactivate an owner (returns 400 error: “Cannot deactivate an owner”)
  • Only one owner is allowed per account

Deactivated users

You cannot update attributes (name, role, and so forth) on a user who is currently deactivated (active: false). You must reactivate them first or simultaneously with the update.

Role keys

When assigning custom roles, you must use the role key, and not the human-readable name or ID. Custom roles must exist in the account before they can be assigned.

Email uniqueness

Email addresses must be unique within an account. If you attempt to provision a user with an email that already exists, you will receive a 409 Conflict error.

Field validation

  • givenName and familyName must be ≤ 256 characters each
  • Email addresses must use valid format
  • Role values must be one of: "reader", "writer", "admin", or "noAccess"

Okta compatibility

For Okta requests (identified by User-Agent header starting with “okta”), the customRole string field is not included in responses. Only customRolesArray is returned.

Extension schema declaration

LaunchDarkly’s implementation is lenient and will accept root-level extension attributes (role, customRole, customRolesArray) even if the extension schema is not declared in the schemas array. However, for strict SCIM 2.0 compliance, include urn:ietf:params:scim:schemas:extension:launchdarkly:2.0:User in the schemas array when using these attributes.