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

# Introduction

> Accounts for your team, and accounts for the people who use your product — one API, two planes.

UserKit is two things that usually get built twice.

The **staff plane** is the account system for your own team: users, organizations,
roles carrying permissions, sessions, invitations, two-factor, API keys. It is
what the panel talks to.

The **customer plane** is the account system for *your* users — the people who sign
up to the product you are building. UserKit calls them **contacts**, and they can be
anonymous visitors or identified people, with the identity edges and merges that
tie the two together.

Both live behind one API, at `/v1`, told apart by which credential you present.

<CardGroup cols={2}>
  <Card title="Quickstart" icon="rocket" href="/en/quickstart">
    From a fresh account to your first identified contact.
  </Card>

  <Card title="Architecture" icon="sitemap" href="/en/architecture">
    How the panel, the API and your own product fit together.
  </Card>

  <Card title="Credentials" icon="key" href="/en/concepts/credentials">
    Four token families, four surfaces, no overlap.
  </Card>

  <Card title="API reference" icon="terminal" href="/en/api-reference/introduction">
    Every endpoint, with a playground.
  </Card>
</CardGroup>

## The shape of it

Every organization is split into a **live** and a **test** environment, seeded when
the organization is created. Test data and live data share a schema and never
share rows. Which environment a machine request touches is decided by the key you
present — `uk_sk_live_…` or `uk_sk_test_…` — and never by a parameter you send.

Authorization is one query. A user belongs to an organization through a
**membership**, the membership carries a **role**, and a role is a set of
**permissions**. Resolving a session resolves identity, active organization, role
and permissions together, which is why revoking a membership invalidates that
session immediately.

Your users are **contacts**. A contact starts as an anonymous visitor with an
`anonymous_id` and first-touch attribution, and becomes identified when an
`external_id` or a proven email attaches to it. Duplicates are merged by hand,
never silently, and every merge is recorded.

## Two ways to authenticate your users

You pick this per environment, so you can evaluate one mode in test while
production runs the other.

<CardGroup cols={2}>
  <Card title="Hosted" icon="lock" href="/en/customer-auth/hosted">
    UserKit owns the account: sign-up, sign-in, email verification and password
    recovery, all non-enumerable.
  </Card>

  <Card title="Federated" icon="signature" href="/en/customer-auth/federated">
    You already have auth. Your server vouches for a user with an HMAC and
    UserKit trusts the claim.
  </Card>
</CardGroup>

## What you need to start

An account and a key. Sign up at [app.userkit.dev](https://app.userkit.dev), mint
a key in your **test** environment, and point your server at
`https://api.userkit.dev` — the [quickstart](/en/quickstart) goes from there to an
identified contact without you deploying anything.
