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

# Directory Sync (SCIM)

> Connect your identity provider directory to Xenia, decide who gets invited with invite rules, and send those invites

## Overview

Directory Sync connects your identity provider's user directory to Xenia over **SCIM 2.0**, so Xenia
reads the list of people your IT team already maintains instead of asking you to upload it. It works
with or without single sign-on. Like [SSO](/guides/workflows/sso), it is built on
[WorkOS](https://workos.com) — Xenia never speaks SCIM to
your IdP directly, and any directory provider WorkOS supports works the same way from Xenia's side —
Okta, Microsoft Entra ID and Google Workspace among them, plus generic SCIM 2.0 for anything that
speaks the protocol. WorkOS maintains
[the current provider list](https://workos.com/docs/directory-sync); adding one needs no change in
Xenia.

Connecting a directory does **not** create Xenia accounts. It gives you a mirror of the directory you
can read and filter. You then write **invite rules** that decide who from that directory gets a Xenia
account, what role and locations they land in — and press send when you're ready.

<Note>
  Directory Sync is its own add-on, enabled per workspace. Until it is on, the **Directory Sync** item
  does not appear in Settings at all and every Directory Sync endpoint answers `403`. Contact your
  Xenia representative to have it turned on.
</Note>

<Note>
  **SSO is not required.** Directory Sync reads your directory and invites people whether or not you
  use single sign-on — the two are independent add-ons. If you *do* have SSO, the two work together:
  people on a verified SSO domain get a passwordless account and a sign-in link, everyone else gets the
  standard invite. Without SSO, everyone gets the standard invite.
</Note>

<Warning>
  Directory Sync **setup and configuration** is done entirely through the Xenia web app —
  **Settings → Directory Sync**. There is no public API for connecting a directory, managing invite
  rules, or sending invites. The [Provision Users API](/api-reference/endpoints/users/provision-users)
  remains the programmatic path for creating users, and it is the right tool if you already have a
  system of record and don't need Xenia to read your directory.
</Warning>

## Who can configure it

The **Manage Directory Sync** permission, granted to the **Owner** and **Admin** roles by default. An
admin without it sees no Directory Sync item in Settings.

## Connecting a directory

1. Go to **Settings → Directory Sync**. With no directory connected yet, you'll see a
   **Connect directory** action.
2. That opens a WorkOS-hosted setup portal in a new tab. Everything IdP-side happens there — you'll be
   given a SCIM base URL and a bearer token to paste into your identity provider's provisioning
   configuration, along with provider-specific instructions.
3. Complete the steps in your IdP, then return to Xenia. The page picks the connection up on its own;
   there is no "check again" button to press.

<Note>
  The portal link **expires five minutes after it is created**. If you get distracted and come back to a
  dead tab, press the button again for a fresh one — nothing is lost, and no partial state is left
  behind.
</Note>

Once linked, the page shows the provider, the connection state, how many users Xenia has mirrored, and
when it last synced.

## How syncing works

Xenia keeps a local mirror of your directory rather than calling your IdP on every page load. Three
things keep it current, all automatic:

| What           | How often       | What it does                                                                                                      |
| -------------- | --------------- | ----------------------------------------------------------------------------------------------------------------- |
| Event drain    | Every 5 minutes | Applies the individual user-added / user-updated / user-removed events WorkOS has recorded since the last pass    |
| Discovery      | Every 5 minutes | Notices a directory that has just been connected, so a fresh connection appears without waiting for the full pass |
| Full reconcile | Every 6 hours   | Re-reads the whole directory and corrects anything the event stream missed                                        |

A **Sync now** action on the page triggers a reconcile immediately if you don't want to wait.

<Note>
  A user your IdP removes or deactivates is marked as such in the mirror — Xenia keeps the row rather
  than deleting it, so a person who leaves and returns is not treated as a stranger. Removal from your
  directory does **not** deactivate their Xenia account; see [Known limitations](#known-limitations).
</Note>

## Invite rules

A rule is a set of conditions on directory attributes plus the **role** and **location** anyone
matching it should get:

> *When* `groups` contains `IT` → *invite as* **Admin**, scoped to **Lake City**

Rules are ordered, and **evaluated top to bottom — the first match wins.** Someone matching two rules
gets the higher one's role, not both. Anyone matching no rule is left uninvited and gets no access,
deliberately: there is no fallback role on this path, because a fallback would mean emailing your
entire directory.

Conditions combine with **All** (AND) or **Any** (OR), and compare case-insensitively using
`is`, `is not`, `contains`, `does not contain`, or `starts with`.

### What you can write rules against

Everything your provider actually sends, including the structured fields:

| Attribute                                                     | Example values                                                               |
| ------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| `groups`                                                      | `IT`, `Engineering` — group membership, usually the most useful one          |
| `role` / `roles`                                              | The role slug your IdP assigns, where your provider supports role assignment |
| `department_name`, `division_name`, `cost_center_name`        | Your org structure                                                           |
| `job_title`, `employee_type`, `employee_number`               | `Full Time`, `Contractor`                                                    |
| `manager_email`, `manager_name`, `manager_id`                 | Reporting line                                                               |
| `addresses.locality`, `addresses.region`, `addresses.country` | Site and region, for scoping to locations                                    |
| `emails`, `phone_numbers`, `username`, `display_name`, `name` | Identity                                                                     |
| `employment_start_date`                                       | ISO date as sent                                                             |

Multi-valued attributes are matched per value, not against a joined string — someone in both
`Engineering` and `IT` matches a rule looking for either, and does not match one looking for
`Engineer` as a substring of the concatenation.

<Note>
  The rule builder lists the attributes your directory has actually sent, with sample values, alongside
  the full set of standard attributes. If an attribute you expect is missing, your IdP is not populating
  it — that is a mapping change on your provider's side, not a Xenia setting. Group-to-role assignment in
  particular is only supported by SCIM-based and Google Workspace directories.
</Note>

<Warning>
  A rule against an attribute your provider never sends matches nobody rather than everybody. That is
  intentional, but it does mean a typo in an attribute name reads as "0 matched" rather than an error.
</Warning>

## Sending invites

Two ways, and both create Xenia accounts — this is an import, not a request queue:

* **From the rules.** Everyone matching an active rule who doesn't already have an account.
* **By hand.** Tick people in the directory user list and invite just them, choosing the role and
  locations for that selection. No rule needs to exist.

### Which email each person gets

The recipient's **email domain** decides. There is no per-invite choice, deliberately — offering one
would let an admin promise SSO sign-in to someone whose domain cannot use it:

| Recipient                                                | What Xenia creates                         | What they receive                                                  |
| -------------------------------------------------------- | ------------------------------------------ | ------------------------------------------------------------------ |
| Email domain is a verified SSO domain for this workspace | An **Active** account with **no password** | A sign-in link that takes them through your identity provider      |
| Any other domain                                         | A **Pending** account plus an invite       | The standard Xenia invite email, where they set their own password |
| Already has a Xenia account                              | Membership is ensured if missing           | **Nothing** — see below                                            |

<Note>
  Someone who already has a Xenia account is never re-emailed. Re-running a rule is a sync, not an
  onboarding event, and mailing everyone again on each run is exactly the failure this avoids. Those
  recipients are recorded in the invite log as skipped, with the reason — not as sent, because no email
  was produced.
</Note>

### Pacing and idempotency

* **A mailbox can only be claimed once per workspace.** Pressing send twice does not produce a second
  email; the second press claims nothing and leaves no trace.
* **Sending is paced at 500 emails per hour.** A 10,000-person directory therefore drains over about
  three days rather than in one blast, which keeps your domain's sending reputation intact and gives
  bounce signal time to accrue.
* **A failed invite can be retried.** Failures stay in the log with their reason and are re-armed the
  next time you send, so a recipient who failed once is not stranded.
* **Sending can be paused** for a workspace by Xenia — for example if a large send starts bouncing
  heavily. Pausing stops the drain without discarding what is already queued; it resumes where it left
  off. There is no self-service pause control in the web app today.

### Reading the results

The invite log shows every mailbox Xenia has claimed, its status, the role and locations it was sent
with, and the failure reason where there is one — so "9,842 sent / 570 failed" is a real count rather
than an assumption.

<Warning>
  `Sent` means Xenia's notification service accepted the email for delivery, not that it landed in the
  recipient's inbox. Per-message delivery, bounce and complaint outcomes are not currently correlated
  back into the Directory Sync log — see [Known limitations](#known-limitations).
</Warning>

## Seats

Invites are subject to your workspace's user-seat limit. If a send would exceed it, Xenia refuses the
whole send up front and tells you the shortfall, rather than creating accounts until the limit is hit
and failing the remainder.

## Directory Sync alongside SSO and HRIS

These three overlap, and it's worth being clear on which does what:

|                         | Where the user list lives    | Creates accounts           | When                              |
| ----------------------- | ---------------------------- | -------------------------- | --------------------------------- |
| **SSO**                 | Your IdP, per sign-in        | Yes, just-in-time          | The moment someone first signs in |
| **Directory Sync**      | Your IdP directory, mirrored | Yes, when you send invites | When you choose                   |
| **HRIS integration**    | Your HR system               | Yes, on sync               | On the integration's schedule     |
| **Provision Users API** | Your own system              | Yes                        | When you call it                  |

Directory Sync and SSO are independent add-ons that complement each other. Directory Sync gets people
accounts with the right role and locations *before* they ever sign in; SSO is one of the ways they
then get in. Using SSO alone means the first person through the door lands on the default role with no
locations — see [just-in-time provisioning](/guides/workflows/sso#just-in-time-provisioning). Using
Directory Sync alone is perfectly fine: everyone gets the standard invite and sets their own password.

## Known limitations

* **No deprovisioning on sync.** Removing or deactivating someone in your directory marks them removed
  in the Xenia mirror but does **not** deactivate their Xenia account or revoke their access. Offboard
  them in Xenia, via the web app or the
  [Deactivate User](/guides/workflows/user-lifecycle#deactivate-user) API. Relying on the IdP side
  alone leaves an active Xenia account behind.
* **No continuous auto-provisioning.** Invites are sent when you press send; a person added to your
  directory tomorrow appears in the mirror automatically but is not invited until you send again.
* **No automatic group-to-role mapping.** Xenia does not read a WorkOS group-to-role mapping and apply
  it. Write an invite rule against `groups` with the Xenia role you want instead — same outcome, but
  it is a rule you can see and change.
* **Per-message delivery outcomes are not tracked.** The invite log records what was accepted for
  delivery, not what was delivered, bounced or marked as spam.
* **No configuration API.** Connecting a directory, managing invite rules and sending invites are web
  app only, like SSO configuration.
* **No mobile support.** Directory Sync is configured in the web app; there is no equivalent screen in
  the Xenia mobile apps.
* **No webhooks.** To react to accounts Directory Sync creates, poll the
  [Get Users](/api-reference/endpoints/users/get-users) API.

## Troubleshooting

| You see                                                                | What it means                                                                                                        | What to do                                                                                    |
| ---------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- |
| No **Directory Sync** item in Settings                                 | The add-on isn't enabled for your workspace, or your role lacks **Manage Directory Sync**                            | Contact your Xenia representative, or ask an Owner to grant the permission                    |
| "Directory Sync is not configured on this environment"                 | An environment-level credential is missing — not something an admin can fix                                          | Contact Xenia support                                                                         |
| Directory connected in your IdP, but the page still shows no directory | Discovery runs every 5 minutes                                                                                       | Wait, or press **Sync now**                                                                   |
| Users appear in your IdP but not in Xenia                              | The directory is connected but hasn't synced them yet, or your IdP is not pushing them into the assigned application | Press **Sync now**; if they still don't appear, check the app assignment on your IdP          |
| A rule shows "0 matched" and you expected matches                      | The attribute is spelled differently, or your provider doesn't populate it                                           | Check the attribute list in the rule builder — it shows what your directory has actually sent |
| An invited person never received anything                              | They already had a Xenia account, so no email was sent                                                               | Check the invite log for a skipped row; they already have access and can sign in              |
| Invites stop partway through a large send                              | Sending is paced at 500/hour, or has been paused                                                                     | Nothing to do if paced; check whether sending was paused                                      |
| A send is refused with a seat shortfall                                | The invites would exceed your workspace's user-seat limit                                                            | Free up or add seats, then send again                                                         |

## Next Steps

<CardGroup cols={2}>
  <Card title="Single Sign-On guide" icon="key" href="/guides/workflows/sso">
    How people actually sign in once Directory Sync has given them accounts
  </Card>

  <Card title="Provision Users API" icon="user-plus" href="/api-reference/endpoints/users/provision-users">
    The programmatic path, when you have a system of record instead of a directory
  </Card>

  <Card title="User Lifecycle guide" icon="users" href="/guides/workflows/user-lifecycle">
    Roles, status and offboarding via the API
  </Card>

  <Card title="Get Users" icon="list" href="/api-reference/endpoints/users/get-users">
    Poll for the accounts Directory Sync created
  </Card>
</CardGroup>
