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

# SCIM Provisioning (Okta)

> Automatically create, update, and deactivate Attention users and teams from Okta using SCIM 2.0.

Attention supports [SCIM 2.0](https://datatracker.ietf.org/doc/html/rfc7644) so your identity provider can manage Attention users and teams automatically. Assign someone to the Attention SCIM app in Okta and their account is created; unassign them and it is deactivated.

<Info>
  **SCIM is provisioning, not login.** SCIM creates and updates accounts. Signing in is configured separately — see [Single Sign-On](/workspace-setup/single-sign-on). Most organizations enable both: SSO for authentication, SCIM so users exist before they authenticate. In Okta they also live in **separate apps**: SSO uses your OIDC app, SCIM uses the dedicated app you create in Step 2.
</Info>

## How Attention maps to SCIM

| SCIM resource   | Attention object                           |
| --------------- | ------------------------------------------ |
| User            | User                                       |
| Group           | [Team](/workspace-setup/teams-roles-seats) |
| `active: false` | Deactivated user (reversible)              |

Group membership becomes team membership. Roles are assigned through a custom attribute described below.

## Before you start

* **Admin** role in Attention
* An **organization-level** API key
* Okta Super Admin or Application Admin access

## Step 1: Create an organization-level API key

Follow [API Authentication](/api-authentication) to create a key from **Settings → API Keys**.

<Warning>
  The key must be an **organization-level** key, created by an Admin. A personal API key is rejected on every SCIM request with `403 Organization not found for API key`. If your test connection fails with a 403, this is almost always the reason.
</Warning>

Verify the key works before touching Okta:

```bash theme={null}
curl -i https://api.attention.tech/scim/v2/ServiceProviderConfig \
  -H "Authorization: Bearer YOUR_API_KEY"
```

A `200 OK` with a JSON body means the key is valid and correctly scoped.

## Step 2: Create a dedicated SCIM app in Okta

SCIM runs on its own Okta app, separate from the app your users sign in with.

<Warning>
  **Your SSO app cannot do SCIM.** Okta does not support SCIM provisioning on manually created OIDC apps, so the OIDC **Web Application** from the [SSO guide](/workspace-setup/single-sign-on) has no **Provisioning** tab — and never will. Do not look for one there; create the app below instead.
</Warning>

1. In the Okta Admin Console, go to **Applications → Browse App Catalog**.
2. Search for **SCIM 2.0 Test App (Header Auth)** and add it. Despite the name, this is Okta's standard connector for SCIM APIs that authenticate with a bearer token, and it is suitable for production.
3. Give it a recognizable label such as `Attention SCIM`.
4. Hide it from end users (**Do not display application icon to users**) — this app only provisions; people keep signing in through your existing SSO app.
5. Assign the same people and groups you assign to your SSO app. Okta only provisions users who are assigned to this app.

<Note>
  A custom SAML app with **Enable SCIM provisioning** (General tab → App Settings) works too, if you prefer that route. The rest of this guide applies to it unchanged; only the field labels in Step 3 differ.
</Note>

## Step 3: Configure the SCIM connector

In the SCIM app you just created — not the SSO app — go to **Provisioning → Configure API Integration** and check **Enable API integration**.

| Field     | Value                                       |
| --------- | ------------------------------------------- |
| Base URL  | `https://api.attention.tech/scim/v2`        |
| API Token | your organization-level API key from Step 1 |

Okta sends the key on every request as `Authorization: Bearer YOUR_API_KEY`.

Click **Test API Credentials** (labeled **Test Connector Configuration** on the SAML route) to confirm the connection, then save.

<Note>
  On the custom SAML route the same screen is labeled differently: **SCIM connector base URL** (same URL), **Authentication Mode** = `HTTP Header`, the API key in **Authorization**, **Unique identifier field for users** = `userName`, and the **Push New Users, Push Profile Updates, Push Groups** provisioning actions enabled.
</Note>

<Warning>
  **The unique user identifier must be `userName`.** Attention only supports filtering users by `userName` and `active`. If your app lets you change the identifier (the custom SAML route does) and it is set to anything else (`email`, `externalId`, `id`), the lookup filter is ignored rather than rejected, Okta receives your entire user list, and it may match the wrong person — silently applying updates to the wrong account.
</Warning>

<Note>
  EU-hosted organizations use `https://api.eu-a.attention.tech/scim/v2`. If you are unsure which applies, ask your Attention point of contact.
</Note>

## Step 4: Enable provisioning to Attention

Under **Provisioning → To App → Edit**, enable:

* **Create Users**
* **Update User Attributes**
* **Deactivate Users**

Deactivation is reversible: re-assigning a user in Okta restores the account with its history intact.

## Step 5: Map user attributes

<Steps>
  <Step title="Required attributes">
    | Okta attribute   | SCIM attribute    |
    | ---------------- | ----------------- |
    | `user.email`     | `userName`        |
    | `user.firstName` | `name.givenName`  |
    | `user.lastName`  | `name.familyName` |

    `userName` must be the user's email address — Attention matches users by email.
  </Step>

  <Step title="Optional attributes">
    `displayName`, `emails`, `locale`, `timezone`, and `preferredLanguage` are accepted and stored where they have an Attention equivalent.
  </Step>
</Steps>

## Step 6: Assign roles (optional)

Roles are set through an Okta-specific extension attribute rather than the standard SCIM `roles` field.

<Steps>
  <Step title="Get your role UUIDs">
    Call the roles endpoint with your API key:

    ```bash theme={null}
    curl https://api.attention.tech/v2/organizations/roles \
      -H "Authorization: Bearer YOUR_API_KEY"
    ```
  </Step>

  <Step title="Add a custom attribute in Okta">
    In the Okta **Profile Editor** for the SCIM app from Step 2, add a string attribute:

    * **External namespace:** `urn:okta:onprem_app:1.0:user:custom`
    * **External name:** `roleUUID`
  </Step>

  <Step title="Map it">
    Map the attribute to the role UUID you want each user to receive — a constant value, or an expression driven by Okta group membership.
  </Step>
</Steps>

The resulting request looks like this:

```json theme={null}
{
  "schemas": [
    "urn:ietf:params:scim:schemas:core:2.0:User",
    "urn:okta:onprem_app:1.0:user:custom"
  ],
  "userName": "jane.smith@company.com",
  "name": { "givenName": "Jane", "familyName": "Smith" },
  "active": true,
  "urn:okta:onprem_app:1.0:user:custom": {
    "roleUUID": "550e8400-e29b-41d4-a716-446655440000"
  }
}
```

<Note>
  A user holds **one role per organization**. Sending `roleUUID` replaces any role the user currently has, including one set manually in Attention. The role must belong to your organization or the request fails with `400`.
</Note>

<Warning>
  The standard SCIM `roles` array is **not supported**. A payload containing `roles` succeeds but assigns no role — it fails silently. Use the custom extension above.
</Warning>

## Step 7: Push groups as teams

In the SCIM app, open the **Push Groups** tab and push the Okta groups that should exist as Attention teams. Each pushed group becomes a team, and its members become team members.

Push users before groups. Okta creates users first and then reconciles group membership, which is the order Attention expects.

## Provisioning behavior

<AccordionGroup>
  <Accordion title="Users created without a group">
    A user provisioned before any group is pushed is placed in your organization's **Default** team, created automatically on first use. Once Push Groups runs, they gain their real team memberships and keep the Default membership until it is removed.
  </Accordion>

  <Accordion title="Seat type">
    Provisioned users receive a **Recording seat** — the Attention bot can join and record their meetings. To change someone to a Listener seat, edit the user in Attention; see [Teams, Roles & Seats](/workspace-setup/teams-roles-seats).
  </Accordion>

  <Accordion title="Deactivating a user">
    Unassigning a user in Okta sends `active: false`, which deactivates the account without destroying data. Re-assigning restores it. `DELETE /Users/{id}` behaves the same way — it deactivates rather than erases.
  </Accordion>

  <Accordion title="Deleting a group">
    Deleting or unpushing a group archives the Attention team and hides it from group listings, but **does not remove its members**. Those users remain active in Attention.

    Deleting a group is not an offboarding action. To offboard people, deactivate each user.
  </Accordion>

  <Accordion title="Users who were already invited">
    If someone was invited through Attention and is later provisioned via SCIM, the pending invitation is linked to the new account and its role is applied, unless the SCIM request specifies a role of its own.
  </Accordion>

  <Accordion title="Repeated or retried requests">
    Creating a user who already exists returns the existing account rather than an error, so Okta retries are safe. Re-adding a user who is already a team member is likewise harmless.
  </Accordion>
</AccordionGroup>

## Limitations

* **Filtering** — only `userName eq` and `active eq` are supported, combined with `and`. Operators such as `ne`, `co`, `sw`, `gt`, and `lt` are not supported, and unsupported filters are ignored rather than rejected.
* **Page size** — listings return at most 100 resources per request. Use `startIndex` and `count` to page.
* **`roles` attribute** — not supported; use the custom extension in Step 6.
* **`externalId`** — accepted but not stored, and not returned as sent. Do not rely on it as a correlation key.
* **Group membership via `PUT /Users/{id}`** — ignored. Change membership through the Groups endpoint, or with `PATCH /Users/{id}` using `add` or `remove` on `groups`.
* **`/Me`** — not implemented.

## Troubleshooting

<AccordionGroup>
  <Accordion title="No Provisioning tab on the app">
    You are looking at the SSO (OIDC) app. Okta does not support SCIM provisioning on OIDC apps, so that tab will never appear there. Create the dedicated SCIM app from Step 2 and configure provisioning on it.
  </Accordion>

  <Accordion title="401 Unauthorized">
    The `Authorization` header is missing or the key is invalid. Confirm the header is `Bearer YOUR_API_KEY` and that the key has not been deleted.
  </Accordion>

  <Accordion title="403 Organization not found for API key">
    The key is a personal key, not an organization-level one. Have an Admin create an organization-level key and update Okta. See Step 1.
  </Accordion>

  <Accordion title="400 team ... not found in organization">
    A pushed group references a team that does not exist in your organization. Re-push the group so Attention creates it, then retry the user.
  </Accordion>

  <Accordion title="400 user ... already exists in a different organization">
    The email address already belongs to a user in another Attention organization. Contact support — this cannot be resolved from Okta.
  </Accordion>

  <Accordion title="404 Not Found on a user or group">
    The resource does not exist in your organization, or it belongs to another one. Confirm you are using the ID Attention returned when the resource was created.
  </Accordion>

  <Accordion title="Duplicate key errors when adding members">
    Harmless — the user is already a member of the team. It usually means Okta retried or ran overlapping sync jobs.
  </Accordion>
</AccordionGroup>

Okta records every request under **Reports → System Log** (filter on your SCIM app), which is the fastest place to see the exact payload and response.

## Next steps

<CardGroup cols={2}>
  <Card title="Single Sign-On" icon="key" href="/workspace-setup/single-sign-on">
    Configure Okta, Google, or EntraID authentication
  </Card>

  <Card title="Teams, Roles & Seats" icon="user-group" href="/workspace-setup/teams-roles-seats">
    Understand what roles and seat types grant
  </Card>
</CardGroup>

<Info>
  Need help with SCIM provisioning? Contact [support@attention.com](mailto:support@attention.com) or your Attention account manager.
</Info>
