Stitchflow
Khoros logo

Khoros User Management API Guide

API workflow

How to automate user lifecycle operations through APIs with caveats that matter in production.

UpdatedMar 11, 2026

Summary and recommendation

The Khoros Community REST API is available at `https://{community-domain}/api/2.0` and supports core user lifecycle operations: create, read, update, ban, and soft-delete (anonymize). Authentication uses session tokens obtained via Basic Auth or LithiumSSO shared-secret token generation; there is no fine-grained OAuth scope system, so admin-level credentials are required for most user management calls.

LiQL (Lithium Query Language) is the primary mechanism for querying user collections. Standard REST list endpoints have limited filtering; structured queries against the `/api/2.0/search` endpoint with `SELECT ... FROM users WHERE ...` syntax are required for any meaningful filtering or bulk export.

Max `LIMIT` per LiQL query is 1000; use `OFFSET` pagination for larger sets.

For teams building against an identity graph, the `sso_id` field on the user object is the recommended join key between Khoros and the upstream IdP.

It must be populated at account creation or via SSO JIT - not all community configurations expose `sso_id` in LiQL by default, so verify field availability in your instance before relying on it for cross-system identity resolution.

API quick reference

Has user APIYes
Auth methodLithiumSSO token or HTTP Basic Auth (admin credentials); OAuth 2.0 referenced for SSO integrations but REST API primarily uses session/token-based auth
Base URLOfficial docs
SCIM availableNo
SCIM plan requiredEnterprise

Authentication

Auth method: LithiumSSO token or HTTP Basic Auth (admin credentials); OAuth 2.0 referenced for SSO integrations but REST API primarily uses session/token-based auth

Setup steps

  1. Obtain admin credentials or a service account for your Khoros Community instance.
  2. Authenticate via POST to /api/2.0/auth/signInWithClientCredentials or use Basic Auth header with base64-encoded admin:password.
  3. Retrieve the session token (value field) from the authentication response.
  4. Pass the token as a cookie (lithiumSSO={token}) or as a query parameter (restapi.session_key) on subsequent requests.
  5. For SSO-integrated environments, configure LithiumSSO shared secret in Community Admin > System > SSO settings and generate tokens server-side using the shared secret.

User object / data model

Field Type Description On create On update Notes
id integer Unique numeric identifier for the user auto-assigned immutable Internal Khoros user ID
login string Username / login handle required supported Must be unique within the community
email string User's email address required supported Used for notifications and account recovery
password string User password (write-only) required (unless SSO) supported Never returned in GET responses
first_name string User's first name optional supported Profile field
last_name string User's last name optional supported Profile field
biography string User bio / about me text optional supported Profile field
avatar object User avatar image reference optional supported Contains profile_image URL
rank object User's community rank object auto-assigned admin-only Contains rank name and id
roles array Roles assigned to the user optional supported (admin) Controls permissions within the community
registration_time datetime Timestamp of user registration auto-assigned immutable ISO 8601 format
last_visit_time datetime Timestamp of user's last visit auto-assigned system-managed Read-only
status string Account status (e.g., enabled, banned) optional supported (admin) Values: enabled, banned, anonymous
banned boolean Whether the user is banned optional supported (admin) Setting true bans the user
deleted boolean Whether the user account is deleted/anonymized n/a supported (admin) Soft-delete; anonymizes PII
sso_id string External SSO identifier for the user optional supported Used to link Khoros account to external IdP identity
kudos_received integer Total kudos (likes) received by the user auto system-managed Read-only engagement metric
messages_count integer Total posts/messages authored by the user auto system-managed Read-only

Core endpoints

Get User by ID

  • Method: GET
  • URL: https://{community-domain}/api/2.0/users/{user_id}
  • Watch out for: Requires admin credentials or a session token with sufficient privileges. Regular user tokens can only retrieve their own profile.

Request example

GET /api/2.0/users/12345
Authorization: Basic {base64(admin:password)}

Response example

{
  "status": "success",
  "data": {
    "type": "user",
    "id": 12345,
    "login": "jdoe",
    "email": "jdoe@example.com"
  }
}

List Users (LiQL query)

  • Method: GET
  • URL: https://{community-domain}/api/2.0/search?q=SELECT+*+FROM+users+LIMIT+10
  • Watch out for: LiQL (Lithium Query Language) is the primary way to query collections. Max LIMIT is 1000 per query. Use OFFSET for pagination.

Request example

GET /api/2.0/search?q=SELECT id,login,email FROM users LIMIT 10 OFFSET 0
Authorization: Basic {base64(admin:password)}

Response example

{
  "status": "success",
  "data": {
    "type": "users",
    "list": [
      {"id": 1, "login": "alice"},
      {"id": 2, "login": "bob"}
    ]
  }
}

Create User

  • Method: POST
  • URL: https://{community-domain}/api/2.0/users
  • Watch out for: Admin credentials required. Email verification may be triggered depending on community settings. SSO communities may use JIT provisioning instead.

Request example

POST /api/2.0/users
Content-Type: application/json

{"login":"newuser","email":"new@example.com","password":"Str0ng!"}

Response example

{
  "status": "success",
  "data": {
    "type": "user",
    "id": 99001,
    "login": "newuser"
  }
}

Update User

  • Method: PUT
  • URL: https://{community-domain}/api/2.0/users/{user_id}
  • Watch out for: Full PUT semantics; omitting optional fields may reset them. Use only fields you intend to change and verify field behavior in your community version.

Request example

PUT /api/2.0/users/12345
Content-Type: application/json

{"first_name":"Jane","biography":"Updated bio"}

Response example

{
  "status": "success",
  "data": {
    "type": "user",
    "id": 12345,
    "first_name": "Jane"
  }
}

Delete (Anonymize) User

  • Method: DELETE
  • URL: https://{community-domain}/api/2.0/users/{user_id}
  • Watch out for: Khoros performs a soft-delete / anonymization rather than hard deletion. User content is retained but PII is scrubbed. This action is irreversible.

Request example

DELETE /api/2.0/users/12345
Authorization: Basic {base64(admin:password)}

Response example

{
  "status": "success",
  "message": "User anonymized successfully"
}

Ban User

  • Method: PUT
  • URL: https://{community-domain}/api/2.0/users/{user_id}
  • Watch out for: Banning is done via the update endpoint. Banned users cannot log in but their content remains visible unless separately moderated.

Request example

PUT /api/2.0/users/12345
Content-Type: application/json

{"banned":true}

Response example

{
  "status": "success",
  "data": {
    "type": "user",
    "id": 12345,
    "banned": true
  }
}

Assign Role to User

  • Method: POST
  • URL: https://{community-domain}/api/2.0/users/{user_id}/roles
  • Watch out for: Role IDs are community-specific strings. Retrieve available roles via GET /api/2.0/roles before assigning. Board-scoped roles require specifying the board context.

Request example

POST /api/2.0/users/12345/roles
Content-Type: application/json

{"role":{"id":"moderator"}}

Response example

{
  "status": "success",
  "data": {
    "type": "role",
    "id": "moderator"
  }
}

Get User by SSO ID (LiQL)

  • Method: GET
  • URL: https://{community-domain}/api/2.0/search?q=SELECT+*+FROM+users+WHERE+sso_id+%3D+%27{sso_id}%27
  • Watch out for: sso_id field must be populated at account creation or via SSO JIT. Not all community configurations expose sso_id in LiQL queries.

Request example

GET /api/2.0/search?q=SELECT id,login,email FROM users WHERE sso_id = 'ext-user-abc123'
Authorization: Basic {base64(admin:password)}

Response example

{
  "status": "success",
  "data": {
    "type": "users",
    "list": [{"id": 12345, "login": "jdoe"}]
  }
}

Rate limits, pagination, and events

  • Rate limits: Khoros Community REST API rate limits are not publicly documented with specific numeric thresholds. Limits are enforced per community instance and may vary by plan. Excessive requests result in HTTP 429 responses.
  • Rate-limit headers: No
  • Retry-After header: No
  • Rate-limit notes: No official public documentation of specific rate limit values. Contact Khoros support for instance-level limits. HTTP 429 is returned when limits are exceeded.
  • Pagination method: offset
  • Default page size: 10
  • Max page size: 1000
  • Pagination pointer: page.offset / page.size (LiQL queries) or start / count (REST v2 list endpoints)
Plan Limit Concurrent
Standard/Enterprise Not publicly specified; enforced per instance 0
  • Webhooks available: No
  • Webhook notes: Khoros Community does not offer a native outbound webhook system for user lifecycle events as documented in official developer docs. Event-driven integrations are typically handled via Khoros Flow (automation product) or polling the REST API.
  • Alternative event strategy: Use Khoros Flow (if licensed) for event-driven automation, or poll the REST API using LiQL queries filtered by registration_time or last_visit_time to detect new/changed users.

SCIM API status

  • SCIM available: No
  • SCIM version: Not documented
  • Plan required: Enterprise
  • Endpoint: Not documented

Limitations:

  • Khoros Community does not natively support SCIM 2.0 provisioning as of available documentation.
  • User provisioning is handled via JIT (Just-in-Time) provisioning through SAML SSO.
  • Enterprise plan required for SSO/JIT provisioning features.
  • No SCIM endpoint is documented in the official Khoros developer portal.
  • Deprovisioning must be handled manually via the REST API or by disabling SSO access at the IdP level.

Common scenarios

Provisioning a new user via the API requires a POST to /api/2.0/users with login, email, and either password or sso_id. In SSO-enabled communities, REST-created accounts and JIT-provisioned accounts can conflict if the same email or sso_id is used - confirm account coexistence behavior with your Khoros admin before building this flow.

Deprovisioning should follow a two-step sequence: first ban the user via PUT /api/2.0/users/{user_id} with {"banned": true} to immediately block login, then issue DELETE /api/2.0/users/{user_id} if PII removal is required. Critically, DELETE performs a soft anonymization - the user record and content are retained, only PII is scrubbed, and the action is irreversible. Disable the IdP account before or in parallel; if SSO remains active, JIT can re-provision a new account after anonymization.

Bulk export for audit or identity graph sync uses paginated LiQL: SELECT id, login, email, registration_time, status FROM users LIMIT 1000 OFFSET {n}. For communities with large member bases, filter by registration_time ranges to support incremental syncs and reduce per-page latency. Custom profile fields are community-specific and must be queried by their configured field names, which are not standardized across instances.

Provision a new community user from an external system

  1. Authenticate to the Khoros Community REST API using admin credentials via POST or Basic Auth header.
  2. POST to /api/2.0/users with required fields: login, email, password (or sso_id for SSO environments).
  3. Capture the returned user id for future reference.
  4. Optionally assign roles via POST /api/2.0/users/{user_id}/roles using the appropriate role id.
  5. Store the Khoros user id mapped to the external system's user identifier for future updates.

Watch out for: If the community uses SSO/JIT provisioning, creating users via the REST API may conflict with SSO-managed accounts. Confirm with Khoros admin whether REST-created accounts can coexist with SSO accounts.

Deprovision a user when they leave the organization

  1. Look up the user's Khoros id using a LiQL query: SELECT id FROM users WHERE sso_id = '{external_id}' or WHERE email = '{email}'.
  2. Ban the user immediately to prevent login: PUT /api/2.0/users/{user_id} with {"banned": true}.
  3. If full removal is required for GDPR/privacy compliance, issue DELETE /api/2.0/users/{user_id} to anonymize the account.
  4. Disable or remove the user's SSO access at the IdP level (e.g., Entra ID) to prevent JIT re-provisioning.

Watch out for: DELETE anonymizes rather than hard-deletes. If the user re-authenticates via SSO after anonymization, JIT provisioning may create a new account. Disable IdP access first.

Bulk-export users for audit or sync

  1. Use LiQL via GET /api/2.0/search?q=SELECT id,login,email,registration_time,status FROM users LIMIT 1000 OFFSET 0.
  2. Iterate through pages by incrementing OFFSET by 1000 until the returned list size is less than 1000.
  3. For each user, optionally fetch extended profile fields via GET /api/2.0/users/{user_id} if LiQL does not expose custom fields.
  4. Write results to your target system, mapping Khoros user id to external identifiers.

Watch out for: LiQL LIMIT is capped at 1000. For communities with large user bases, pagination via OFFSET can be slow. Filter by registration_time ranges to reduce result sets for incremental syncs.

Why building this yourself is a trap

The most significant integration trap is the ban/JIT re-provisioning gap. Banning a user via the API sets banned: true on the Khoros record but has no effect on the upstream IdP session.

If the IdP account remains active, the user can re-authenticate via SSO and JIT will create a new Khoros account, silently bypassing the ban. Any deprovision workflow that does not include an IdP-side disable step is incomplete.

Authentication tokens obtained via Basic Auth are session-scoped and subject to expiration. Long-running integrations must implement token refresh logic; there is no documented token TTL, so treat any 401 response as a signal to re-authenticate rather than a hard failure.

Rate limits are not publicly documented with numeric thresholds. HTTP 429 is returned when limits are exceeded, but no Retry-After header is provided. Production integrations must implement exponential backoff.

For teams using an MCP server with 60+ deep IT/identity integrations, Khoros should be treated as a polling-dependent source - there is no native webhook system for user lifecycle events. Event-driven patterns require either Khoros Flow (if licensed) or scheduled LiQL polling filtered by registration_time or last_visit_time.

Automate Khoros workflows without one-off scripts

Stitchflow builds and maintains end-to-end IT automation across your SaaS stack, including apps without APIs. Built for exactly how your company works, with human approvals where they matter.

Every app coverage, including apps without APIs
60+ app integrations plus browser automation for apps without APIs
IT graph reconciliation across apps and your IdP
Less than a week to launch, maintained as APIs and admin consoles change
SOC 2 Type II. ~2 hours of your team's time

UpdatedMar 11, 2026

* Details sourced from official product documentation and admin references.

Keep exploring

Related apps

Abnormal Security logo

Abnormal Security

API Only
AutomationAPI only
Last updatedMar 2026

Abnormal Security is an enterprise email security platform focused on detecting and investigating threats such as phishing, account takeover (ATO), and vendor email compromise. It does not support SCIM provisioning, which means every app in your stack

ActiveCampaign logo

ActiveCampaign

API Only
AutomationAPI only
Last updatedFeb 2026

ActiveCampaign uses a group-based permission model: every user belongs to exactly one group, and all feature-area access (Contacts, Campaigns, Automations, Deals, Reports, Templates) is configured at the group level, not per individual. The default Adm

ADP logo

ADP

API Only
AutomationAPI only
Last updatedFeb 2026

ADP Workforce Now is a mid-market to enterprise HCM platform that serves as the HR source of record for employee data — payroll, benefits, time, and talent. User access is governed by a hybrid permission model: predefined security roles (Security Maste