> ## Documentation Index
> Fetch the complete documentation index at: https://docs.inworld.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# SCIM Provisioning

> Automate Inworld membership from your identity provider with SCIM 2.0.

<Note>
  SCIM provisioning is in **private preview**. [Contact sales](https://inworld.ai/contact-sales) or your account team to have it enabled for your organization.
</Note>

SCIM 2.0 ([RFC 7644](https://www.rfc-editor.org/rfc/rfc7644)) lets your identity provider own Inworld membership. Assign someone to the Inworld app in Okta or Microsoft Entra ID and they become a member; move them between groups and their role changes; unassign or offboard them and their access is removed — all without anyone touching the Portal.

SCIM is available on the **Enterprise** plan and is configured by **Owners** on the **Domains & SSO** tab of the [Team page](https://platform.inworld.ai/settings/team). Admins can view the configuration.

## Before you start

You need all of the following:

* A [Team account](/portal/org-management) on the **Enterprise** plan.
* At least one [**verified** email domain](/portal/org-domains). SCIM can only provision users whose email is at a domain your organization has verified.
* At least one workspace [shared with the team](/portal/org-management#why-a-shared-workspace-is-required), so provisioned members have somewhere to land. This is checked once, when you enable SCIM.
* [SAML SSO](/portal/sso) configured. SCIM is not strictly dependent on it, but provisioned users need a way to sign in, and pre-provisioned accounts link themselves on their first SSO sign-in.

## Set up SCIM

<Steps>
  <Step title="Enable SCIM provisioning">
    On the **Domains & SSO** tab, turn on **SCIM provisioning**. If a prerequisite is missing the toggle explains which one.
  </Step>

  <Step title="Generate a token">
    Click **Generate token**, give it a description such as `Okta production`, and copy the token immediately.

    <Warning>The token is shown **once**. Inworld stores only a hash and cannot display it again. If you lose it, revoke it and generate a new one.</Warning>
  </Step>

  <Step title="Connect your IdP">
    In your IdP's provisioning settings, paste:

    | Field                    | Value                                                             |
    | ------------------------ | ----------------------------------------------------------------- |
    | Tenant URL / Base URL    | Copy the **Base URL** shown in the Portal — it ends in `/scim/v2` |
    | Secret token / API token | The token you just generated                                      |

    Entra calls it a *Secret Token*; Okta calls it an *API Token*. Use your IdP's **Test Connection** before saving.
  </Step>

  <Step title="Map attributes and push groups">
    Map your users' work email to `userName`, and keep the default mappings for `name.givenName`, `name.familyName`, `displayName`, and `active`. Enable Push Groups (Okta) or group provisioning (Entra) for the groups you want to use for role assignment.
  </Step>

  <Step title="Map groups to roles">
    Groups your IdP pushes appear in the Portal under SCIM provisioning. Set each one's role to **Admin**, **Member**, or leave it **Not mapped**. See [Roles from groups](#roles-from-groups).
  </Step>
</Steps>

## What SCIM manages

| Operation in your IdP               | Effect in Inworld                                           |
| ----------------------------------- | ----------------------------------------------------------- |
| Assign a user to the app            | Member added to your organization                           |
| User already has an Inworld account | Existing account adopted under SCIM management              |
| User has no Inworld account yet     | Account pre-created; it links up at their first SSO sign-in |
| Change name / email                 | Profile and login email updated                             |
| Add to / remove from a pushed group | Organization role recomputed                                |
| Deactivate or unassign the user     | Access removed — see [Deprovisioning](#deprovisioning)      |

### Supported attributes

`/Users` supports the core SCIM user schema:

| Attribute                           | Notes                                                                                       |
| ----------------------------------- | ------------------------------------------------------------------------------------------- |
| `userName`                          | **Required.** The user's work email. Must be at a verified domain. Unique per organization. |
| `name.givenName`, `name.familyName` | Optional.                                                                                   |
| `displayName`                       | Optional. Mirrored to the user's Inworld profile name.                                      |
| `externalId`                        | Optional. Stored and filterable.                                                            |
| `active`                            | Controls provisioning and deprovisioning.                                                   |

`emails` is accepted where your IdP uses it to match users, but the **work email is the `userName`** in this model — there is no separate email list to maintain.

Attributes your IdP sends that Inworld does not model are ignored rather than rejected, so extra mappings in your tenant will not put the sync into an error loop.

### Roles from groups

Groups exist purely to assign organization roles. Your IdP owns which groups exist and who is in them; the Portal owns what each group grants.

* A member whose groups include **any** group mapped to **Admin** gets the **Admin** role.
* Everyone else gets **Member**. Mapping a group to *Member* only documents that intent — Member is the floor either way.
* **Owner cannot be granted through SCIM.** Owners are managed in the Portal only.
* Changing a mapping, or a group's membership, recomputes the affected members' roles immediately.

### Owners are never SCIM-managed

An Owner cannot be adopted, deactivated, or deleted through SCIM — those requests are rejected. Keep your Owners out of the groups you assign to the Inworld app, and manage them on the [Team page](/portal/org-management#organization-roles).

## Deprovisioning

Setting `active` to `false`, or issuing a `DELETE`, removes the person's access to your organization:

* their organization membership is removed;
* their memberships in that organization's workspaces are removed;
* their Inworld sign-in is disabled and existing sessions are revoked.

<Warning>Deprovisioning disables the identity, not just the membership. Your organization owns the verified domain, so a corporate identity is treated as ending with the assignment.</Warning>

A deactivated user's SCIM record stays queryable — with `active: false` — until your IdP issues an explicit `DELETE`. Re-activating (`active: true`) restores membership with the role their groups currently grant, and re-enables sign-in.

## Managed members in the Portal

While SCIM is enabled, members with an active SCIM record are marked **Synced** on the Team page and cannot be edited or removed there — their membership and role come from your IdP. To take manual control, turn **SCIM provisioning** off; the lock is released and existing records and tokens are kept for when you re-enable it.

## Manage tokens

* Up to **10 active tokens** per organization, so you can rotate without downtime and connect more than one IdP.
* The Portal lists each token's description, prefix, creation date, and a coarse **Last used** timestamp.
* **Revoking** a token takes effect immediately — requests using it are refused on the next call.

To rotate: generate a new token, update your IdP, confirm a successful sync, then revoke the old one.

## Protocol details

| Aspect         | Support                                                                                                                                                         |
| -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Resources      | `/Users`, `/Groups`                                                                                                                                             |
| Operations     | `POST`, `GET`, `PUT`, `PATCH`, `DELETE`                                                                                                                         |
| Discovery      | `/ServiceProviderConfig`, `/ResourceTypes`, `/Schemas`                                                                                                          |
| Authentication | `Authorization: Bearer <token>`                                                                                                                                 |
| Content type   | `application/scim+json` (plain `application/json` also accepted)                                                                                                |
| Filtering      | `attribute eq "value"`, optionally joined by `and`. Users: `userName`, `externalId` (and your IdP's email-matching forms). Groups: `displayName`, `externalId`. |
| Pagination     | `startIndex` and `count`; default and page size 100, maximum 200                                                                                                |
| Not supported  | Bulk operations, sorting, ETags, password change or sync                                                                                                        |
| Rate limit     | 600 requests per minute per token; over that returns `429` with `Retry-After: 60`                                                                               |

### Error responses

Errors use the standard SCIM error envelope.

| Status | When                                                                                                                               |
| ------ | ---------------------------------------------------------------------------------------------------------------------------------- |
| `400`  | Invalid value (e.g. a `userName` at an unverified domain), unsupported filter, or an attempt to change something SCIM does not own |
| `401`  | Missing, malformed, or revoked bearer token                                                                                        |
| `403`  | SCIM disabled for the organization, or the plan is not entitled                                                                    |
| `404`  | Unknown user or group id                                                                                                           |
| `409`  | A user with that `userName`, or a group with that `displayName`, already exists                                                    |

## Turn SCIM off

Turning the **SCIM provisioning** toggle off stops all SCIM requests and releases the managed-member lock, while keeping records, tokens, and group mappings for a later re-enable. Disabling SCIM and revoking tokens remain available even after a downgrade from Enterprise — only enabling SCIM and generating tokens require an active Enterprise plan.

## Troubleshooting

<AccordionGroup>
  <Accordion title="Test Connection fails">
    Check the Base URL ends in `/scim/v2` and the token is pasted whole (it begins `inw_scim_`). A `403` means SCIM is switched off for the organization or the plan is not entitled; a `401` means the token is wrong or revoked.
  </Accordion>

  <Accordion title="The sync reports that a domain is not verified for this organization">
    SCIM only provisions users at your [verified domains](/portal/org-domains). Verify the domain, or exclude those users from the app assignment. Subdomains count as separate domains.
  </Accordion>

  <Accordion title="A user was provisioned but cannot sign in">
    Expected for a pre-provisioned account until the person signs in for the first time through [SSO](/portal/sso), which links the identity. Confirm SSO is enabled and the user is assigned to the SAML app too.
  </Accordion>

  <Accordion title="Role changes are not taking effect">
    Roles come from group mappings. Confirm the group is actually being pushed to Inworld (it must appear in the Portal's group list), that it is mapped to **Admin**, and that the user is in it. A user in no Admin-mapped group is a Member by design.
  </Accordion>

  <Accordion title="An Owner fails to sync">
    Owners cannot be managed through SCIM. Remove them from the groups assigned to the Inworld app; manage their role on the Team page.
  </Accordion>

  <Accordion title="The sync reports 409 conflicts">
    Another record already holds that `userName` or group `displayName` — often a user provisioned earlier under a different IdP identity, or a duplicate group name. Reconcile in your IdP, or delete the stale record.
  </Accordion>
</AccordionGroup>

## Next steps

<CardGroup cols={2}>
  <Card title="SAML SSO" icon="key" href="/portal/sso">
    The sign-in half of the story.
  </Card>

  <Card title="Team management" icon="user-group" href="/portal/org-management">
    Roles, invitations, and membership.
  </Card>
</CardGroup>
