End users of partner applications — tenant-scoped identities with their own registration and space access.
Consumers are not admins — and one email is not one person.
Consumers are the end users of partner applications built on KeenAgents (and of Keen's own first-party surface). They are a completely separate population from organization accounts: they have their own registration flows, their own sign-in, and their own admin pages. An organization admin account and a consumer account never mix — even when they share an email address.
The load-bearing identity rule is tenant scoping: a consumer's email is unique only per tenant. Each partner site is a tenant, identified by a 19-character consumer-contract key shared with that partner. The same email can therefore hold one account under partner A, another under partner B, and a first-party account — all independent, with independent passwords, profiles and space grants. Every login, password reset, profile read and chat query is scoped to the tenant resolved from the calling partner's credentials, so one tenant can never read or authenticate another tenant's users. Requests use a two-token model — the partner backend's application_token plus the consumer browser's access_token — covered in detail on the Authentication page; the self-service flows (password reset, delete, profile, chat) have their own page too.
confirmed status (the invite or registration was completed) and an external marker recording whether the account was created through a partner or by an admin invite. Each account is bound to at most one tenant.key that the partner holds. The contract carries the per-tenant policy: five toggles, a master allowed-spaces set and default space sets for admin-invited and partner-registered consumers. Partner notifications travel through the webhook entry bound to the partner's API key. Every consumer belongs to at most one contract; deleting a contract releases its consumers for re-assignment rather than deleting them.Two ways a consumer comes to exist — the external marker records which.
Outside registration is partner-driven and follows a request → email → confirm handshake — nothing is created until the user proves ownership of the address:
X-Callback-Url (the target of the email link) and the user's details. KeenAgents refuses the request when the tenant's outsideRegistration toggle is off — each tenant can be gated independently.10 minutes from the initial request.System registration is an admin invite from the org console: the account is created unconfirmed and first-party (no tenant) and an activation mail with a one-time link goes out. The user completes name and password on the confirmation page, which marks the account confirmed. Admin-created consumers stay first-party until a contract is bound.
OTP: when policy requires it, login returns a "Verify" challenge instead of signing the user in — a 6-digit pin (100000–999999) is emailed, valid for 120 s and tied to the exact login attempt and site that triggered it; a pin can be tried exactly once. The requirement is contract-first (otpOutsideRegistration / otpInsideRegistration, chosen by how the account was registered), falling back to the org-global settings for first-party logins.
otpOutsideRegistration setting to be on — even when the challenge was triggered by contract-level policy. A tenant with contract OTP enabled but the global flag off sends pins that can never be confirmed.A@x.com and a@x.com are different accounts. Addresses must be a valid email shape.male | female | other, and dob { day, month, year } — all three parts required.10 minutes from the request; an expired link is refused and the flow starts over.[100000, 999999], valid for 120 s, one attempt — a wrong entry spends the challenge and the user signs in again to get a fresh pin.outsideRegistration toggle gates the start of a registration (one tenant can be disabled alone); the org-wide switch gates its completion (master kill-switch). Both must be on for a registration to finish.What operators change, and how partner sites hear about it.
Consumers are managed from the org admin console: viewing requires the Consumer permission; all changes additionally require its Write grant. The consumer list is a paged table with filters — narrow it by the fields you see in the table before paging through — and each row opens the consumer's detail page. From there admins can invite by email, send a password reset, edit the space list, bind / re-bind / unbind the tenant contract (binding clamps spaces to the contract's allowed set; unbinding wipes them; a re-bind that collides with an existing same-email account under the destination tenant is refused), and delete. When a contract is deleted, its consumers are released — they remain, unassigned, and the consumer detail page is where an admin re-assigns each one to a contract. Per-tenant policy lives on the consumer contract page — five toggles plus three space lists, where the defaults must be subsets of the master set and shrinking the master set automatically prunes every bound consumer. Org-wide switches (the global registration kill-switch and the global OTP flags) live in System Consumer Settings.
Partner sites hear about changes through notify-then-fetch webhooks: a lightweight POST says what changed — never the data itself — and the partner re-fetches through the authenticated API. Consumer-targeted pings carry the consumer's id:
targeted consumer ping
POST <your webhook entry's notification URL> { "synch-data": ["r_consumer_spaces_update"], "consumer": { "id": "<consumer id>" } }
r_consumer_spaces_update — an admin changed that consumer's spaces; sent to the current tenant's notification URL (the webhook entry bound to its API key).r_consumer_contract_changed — an admin re-bound or unbound the tenant; sent to the previous tenant's URL, since that site holds the now-stale session.Keen Agents 2026
Documentation
Release 15