Skip to main content
Contacts get into your product one of two ways. You pick per environment, so you can evaluate one in test while production runs the other.

Hosted

UserKit owns the account. Sign-up, sign-in, email verification and password recovery are endpoints you call. You build the forms; the rules are ours.

Federated

You already have auth. Your server vouches for a user with an HMAC over their id, and UserKit trusts the claim.

Which one

If you are starting from nothing, hosted. If your product already has a users table, federated — you are not migrating anyone.

Setting it

Requires organization:update. Both environments start as hosted.

Reading it from a login screen

A sign-in screen has to know which mode it is in before it can render itself, and taking that as configuration means flipping the mode does nothing until somebody redeploys. Ask instead:
200
Public and cacheable — no key beyond the publishable one, no Origin check, so it works from a server rendering the page. providers lists what a contact could actually sign in with, so turning Google on in the panel lights the button up on its own. See Social sign-in.

The modes refuse each other

The endpoints of the mode an environment is not in answer 409 rather than quietly becoming a second sign-in path:
/v1/contact-auth/* on a federated environment
/v1/boot with external_id, on a hosted environment
Two sign-ins into one account system is how the weaker one becomes the way in.
Anonymous boot — a publishable key and an anonymous_id, no external_id — works in both modes. Visitor tracking and attribution are not an authentication question, so they never hit the mode check.

What both modes share

Whichever you pick, the same things hold. Contacts are contacts. Same rows, same identity edges, same attribution, same merges. The mode decides how a contact gets proven, not what one is. Only a link proves an email. In both modes, email_verified flips when a message arriving in the inbox is clicked — never because an email was passed to an API. Sessions carry verified. A proven identity mints a verified contact session; an unproven one mints a session marked unverified and barred from anything another person’s data could leak through. Responses do not enumerate. Sign-up, magic link, resend and forgot-password all answer 202 unconditionally, and sign-in answers one uniform 401, in both modes. The origin list is the gate. Every publishable-key endpoint that writes anything — boot, sign-up, sign-in, magic link, social — checks the allowed-origins list before anything else. The two public reads addressed by key, /v1/config and /v1/jwks, do not: they mint nothing and mail nobody, and gating them would only stop a server rendering your login page, which sends no Origin at all. Your backend verifies the same way. Whichever mode the environment is in, a contact session buys a short-lived JWT your API checks offline. See Session tokens.