Skip to main content

SCIM 2.0 Provisioning

KnoxCall implements RFC 7644 (SCIM Protocol) and RFC 7643 (SCIM Schema) so your identity provider can create, update and deprovision workspace members — and OAuth clients — without anyone logging into KnoxCall. This is the page your connector’s documentationUri points at. If you arrived here from GET /scim/v2/ServiceProviderConfig, you are in the right place.
SCIM provisioning requires the Enterprise plan. Discovery (/ServiceProviderConfig, /Schemas, /ResourceTypes) is served on every plan so that a connector can be configured and can read this URL; the /Users and /OAuthClients endpoints are served to Enterprise workspaces. See Plan requirement for exactly what a workspace sees when the plan does not cover it.

Base URL

The SCIM service lives under /scim/v2 on your workspace’s KnoxCall control-plane host:
https://admin.knoxcall.com/scim/v2 works too. Requests that arrive on any other hostname — including directly to the origin address — are answered 404 before authentication is attempted, so paste the workspace URL exactly. Every endpoint is relative to that base:

Token issuance

Your connector authenticates with a SCIM credential — a bearer token that begins with scim_. It is not a user’s session and not an API key; it belongs to the workspace, carries its own tenant binding, and reaches /scim/v2 and nothing else. To issue one, an owner or admin goes to the KnoxCall dashboard and mints a credential from the Single sign-on settings (POST /admin/scim/credentials if you are scripting it). Minting requires a recent step-up verification, is written to the audit log, and asks for an explicit expiry — a credential with no expiry is something you have to choose, never something you get by omitting a field.
The token is shown exactly once, when it is minted. It is stored only as a SHA-256 digest, so it cannot be recovered — if it is lost, revoke it and mint another.
Use a Live credential for /Users. Workspace membership is not partitioned into Live and Test data spaces — a workspace has one set of people — so a Test credential is refused on /Users with a 403. A Test credential does provision /OAuthClients, which is partitioned.
Revoking a credential takes effect on the connector’s next request: the check is a single indexed lookup evaluated against the database clock, not a cache.

Content type

RFC 7644 §3.1 requires application/scim+json, and KnoxCall accepts it on requests and returns it on responses. application/json is accepted on requests as well, so a connector that sends the plain type is not broken by it.

Supported resources

/Users

A User is a workspace membership plus a directory record. The attributes your IdP asserts live on the directory record, never on the person’s global KnoxCall account — one workspace’s directory must not rename or re-address someone in another workspace. active being derived is the property that matters most in practice: if an administrator removes someone from the workspace on the team page, your next GET reports active: false without KnoxCall having to write anything. Provisioning a new person requires a verified domain. SCIM grants membership without asking the subject to accept an invitation, so KnoxCall applies the same admission rule as SAML just-in-time provisioning: the address must sit within a domain this workspace has proven by DNS. Verify the domain under Settings → Single sign-on first. Someone who is already a member can be given a directory record without this. New memberships are always granted at the member role. A SCIM connector cannot mint an administrator.

Deprovisioning

Both forms end the membership immediately, and neither erases personal data — erasure is a separate, subject-initiated process:
  • PATCH with active: false — the membership is revoked and the directory record stays, so a later GET returns it with active: false. This is the shape Entra sends on a soft-delete.
  • DELETE — the same revocation, plus a tombstone on the directory record, so a later GET returns 404.

/OAuthClients

A custom resource, urn:knoxcall:scim:2.0:OAuthClient, for provisioning machine credentials alongside people. clientName, allowedScopes, redirectUris, requirePkce, requireDpop, stepUpScopes and active are writable; clientId, clientType and grantTypes are not. The client_secret of a confidential client is returned exactly once, on create. Redirect URIs are validated on registration with the same rule the dashboard and the Management API apply — a non-registrable URI is refused with a 400 rather than silently dropped from the list.

Filtering

filter implements the RFC 7644 §3.4.2.2 grammar, not a subset of it:
  • Comparison operators eq, ne, co, sw, ew, gt, ge, lt, le, and the presence operator pr
  • and, or, not, and parentheses
  • Value filters on multi-valued attributes — emails[type eq "work"]
  • URN-qualified attribute names
Attribute names are matched case-insensitively, as RFC 7643 §2.1 requires, except for the identifiers id, externalId and clientId, which RFC 7643 §7 defines as case-exact. userName deliberately folds case, so userName eq "Ada@Example.com" finds the record stored as ada@example.com. A filter KnoxCall cannot honour is answered 400 with scimType: "invalidFilter" — it is never ignored, and you will never receive an unfiltered list in response to a filter we did not understand. Pagination is startIndex (1-based) and count, capped at the filter.maxResults value /ServiceProviderConfig advertises.

Attributes accepted but not stored

Entra’s default user mapping sends attributes KnoxCall has no home for. Rejecting them would refuse the whole PatchOp — including the active: false in the same request — so an offboarding would silently not happen. KnoxCall therefore accepts these, names them in the audit record, and stores none of them: Anything outside that set — an unknown core attribute, a custom extension, a foreign schema URN — is still refused with scimType: "invalidPath", and the schema qualifier on a path is read, so urn:…:enterprise:2.0:User:active does not deactivate anyone.

Plan requirement

SCIM provisioning is an Enterprise feature. Discovery is never gated. /ServiceProviderConfig, /Schemas and /ResourceTypes answer on every plan, so a connector can always be configured and can always read this page’s URL out of the capability document. The resource endpoints are. A workspace whose plan does not include SCIM receives 403 on /Users and /OAuthClients with a SCIM Error object:
The error member is a KnoxCall extension, because RFC 7644 §3.12’s scimType vocabulary is closed and has no value meaning “your plan does not include this”. A SCIM client ignores the extra member; schemas, status and detail are exactly what the RFC specifies. There is no scimType on this refusal — giving it a near-miss value would make a connector retry with a different body forever.

What happens if the subscription lapses

Nothing stops. A workspace whose Enterprise subscription goes past_due, enters dunning or is cancelled keeps being provisioned. An identity provider does not read a 403 as “the invoice is unpaid” — Entra marks the object in error, retries, and eventually quarantines the whole provisioning job, and restarting a quarantined job re-runs a full reconciliation. Turning a card decline into that would churn every member of the workspace at the moment the people who could fix the card are the ones losing access. What a lapse does stop is issuing a new SCIM credential. Minting requires a current Enterprise plan; connectors that already hold one keep working. A workspace that deliberately downgrades to a lower tier is a different case — that is a choice, not an accident of billing — and its resource endpoints are refused as above. Listing and revoking credentials is never gated. A workspace that has stopped paying must still be able to see which connectors hold a credential and switch them off.

Rate limits

An identity provider does not send traffic like a person. Entra reconciles in bursts, retries aggressively, and treats a 429 without a Retry-After header as a hard failure rather than as backpressure. KnoxCall’s limits are built around that. The unit is the workspace deliberately. Entra’s provisioning service egresses from a shared Azure address pool, so two KnoxCall customers’ reconciliations routinely arrive from the same IP; a purely per-address budget would let one customer’s initial sync throttle another’s connector. A separate per-address flood shield still sits in front of the mount, set above the per-workspace budget so that one workspace can never consume it on its own. A 429 body is a SCIM Error object like any other refusal:
Honour Retry-After. A provisioning cycle interrupted by a 429 can be resumed without losing state — nothing was half-applied, because the request was shed before it reached a handler. At 750 requests per minute a full first-time synchronisation of 10,000 users completes in about fifteen minutes, and an incremental cycle never approaches the ceiling.

Error codes

Alongside the RFC 7644 §3.12 members, KnoxCall refusals that the scimType vocabulary cannot express carry an error member: A refusal never states whether some other workspace exists. Your credential binds the request to one workspace, so there is nothing to disambiguate.

Setting up Microsoft Entra ID

  1. Mint a SCIM credential in KnoxCall (Settings → Single sign-on) and copy the scim_… token.
  2. In Entra, open your enterprise application → ProvisioningAutomatic.
  3. Tenant URL: https://<workspace>.knoxcall.com/scim/v2
  4. Secret Token: the scim_… token.
  5. Test Connection — Entra fetches /ServiceProviderConfig and /Schemas.
  6. Leave the default user attribute mapping as it is. The attributes KnoxCall does not store are accepted rather than refused, precisely so that the default mapping works unmodified.
  7. Verify your email domain in KnoxCall before starting the first cycle, or every create for a new person is refused.
Okta is configured the same way: Base URL https://<workspace>.knoxcall.com/scim/v2, OAuth Bearer Token, and Import New Users and Profile Updates + Push New Users + Push Profile Updates + Deactivate Users.

What KnoxCall does not implement

/ServiceProviderConfig is the authoritative answer, and it says so honestly:
  • Bulk operations — not supported
  • Sorting — not supported
  • ETags — not supported
  • changePassword — not supported, and never will be: KnoxCall does not hold member passwords
  • /Groups — not yet exposed