# First boot

> Make the first admin with the one-time setup URL and a passkey, or with an API token.

Checkend has no default password. At the first start, the server makes a one-time setup URL. The person who opens it becomes the first admin.

## The setup URL

The server prints the setup URL at the first start. It looks like this:

```
https://stats.example.com/setup#cesetup_...
```

The server also writes the URL to the file `<data>/setup-url` (mode 0600), until the first admin exists. The installer prints the URL for you. With Docker, find it in the log:

```sh
docker logs checkend 2>&1 | grep setup
```

The token is in the URL fragment (after `#`), so it does not go into an access log.

> **Caution**
> Keep the setup URL private until you use it. Anybody with the URL can make the first admin. A restart of the server makes a new URL, and the old URL does not work after the restart.

## Make the first admin with a passkey

1. Open the setup URL in a browser.
2. Type your email address.
3. Select **Create a passkey**, and follow the steps of your browser or password manager.
4. Select the modules. In this version, only analytics is available.
5. Add the first site. The page shows the install prompt and waits for the first event. See [Add a site](/docs/start/add-a-site.md).
6. Connect an agent. The page shows the MCP URL, a form for an agent token, and the commands for Claude Code, any MCP client and `ce`. See [Connect your agent](/docs/start/connect-your-agent.md).

The page removes the token from the address bar. After this, sign in on `/signin` with **Sign in with a passkey**. You do not type an email address to sign in.

You can add more passkeys later in **Settings**.

## Passkeys need HTTPS or localhost

Passkeys work only on HTTPS with a domain name, or on `localhost`. They do not work on an IP address, or on plain HTTP with a domain name.

- On a server with `--domain`, or behind a proxy with TLS, passkeys work.
- On `127.0.0.1`, the server uses `localhost` for the passkeys. Open the setup URL with `localhost`, not with `127.0.0.1`.
- On a remote server without a domain, open an SSH tunnel, then open the setup URL on your computer:

  ```sh
  ssh -L 8080:localhost:8080 you@server
  ```

## Make the first admin with an API token

Where passkeys do not work, the setup page tells you why. It then offers **Create the admin with an API token**. Use this on a private network with an IP address only.

1. Open the setup URL.
2. Type your email address.
3. Select **Create the admin with an API token**.
4. Copy the token. The page shows it one time.
5. Sign in to the web UI with the token.

You can also make the first admin from a terminal with `ce setup`. Use the token from the setup URL:

```sh
ce setup https://stats.example.com --email you@example.com --setup-token cesetup_...
```

`ce setup` makes the admin and stores the new admin token, as `ce login` does. A wrong or used setup token exits with code 5.

## Automation: no setup step

For automation and CI, make the first admin from environment variables at the first start. Set both variables:

| Variable | Value |
|---|---|
| `CHECKEND_ADMIN_EMAIL` | The email address of the first admin. |
| `CHECKEND_API_TOKEN` | The API token of the admin: `ce_` and at least 32 characters. |

```sh
CHECKEND_ADMIN_EMAIL=ops@example.com CHECKEND_API_TOKEN=ce_<at least 32 characters> \
  checkend serve --data /var/lib/checkend
```

Then use the token with `ce`:

```sh
CHECKEND_URL=https://stats.example.com CHECKEND_TOKEN=ce_... ce sites list
```

> **Caution**
> Keep `CHECKEND_API_TOKEN` in a secret store. It is an admin token.

## Next step

[Add a site](/docs/start/add-a-site.md).
