---
title: "Root user programmatic signin"
method: POST
path: "/api/user.rootSignin"
tags: ["Authentication"]
---

# Root user programmatic signin

`POST /api/user.rootSignin`

Authenticates the root user using HMAC signature for programmatic access.
This endpoint is designed for automation scenarios like Infrastructure-as-Code
deployments, CI/CD pipelines, and automated testing where magic link
authentication is impractical.

**Security Features:**
- HMAC-SHA256 signature verification using the application's secret key
- 60-second timestamp window to prevent replay attacks
- Rate limited to 5 attempts per 5 minutes per email
- Only works for a configured root email address (ROOT_EMAIL may list several, comma/semicolon-separated)

**How to generate the signature:**
```bash
SECRET_KEY="your-notifuse-secret-key"
ROOT_EMAIL="admin@example.com"
TIMESTAMP=$(date +%s)
MESSAGE="${ROOT_EMAIL}:${TIMESTAMP}"
SIGNATURE=$(echo -n "$MESSAGE" | openssl dgst -sha256 -hmac "$SECRET_KEY" | awk '{print $2}')
```

## Request body

- RootSigninRequest — Request payload for root user programmatic signin using HMAC signature
  - `email` string, email, required — The root user's email address (must match one of the configured ROOT_EMAIL addresses)
  - `timestamp` integer, required — Unix timestamp (seconds since epoch). Must be within 60 seconds of server time.
  - `signature` string, required — HMAC-SHA256 signature computed as: HMAC-SHA256(email + ":" + timestamp, SECRET_KEY) The signature should be hex-encoded.

## Response `200`

Authentication successful

- RootSigninResponse — Successful authentication response containing JWT token and user details
  - `token` string, required — JWT authentication token for subsequent API requests
  - `user` User, required — User account information
    - `id` string, required — Unique user identifier
    - `email` string, email, required — User's email address
    - `name` string — User's display name
    - `language` string — User's preferred locale for the console UI and system emails
    - `created_at` string, date-time — Account creation timestamp
    - `updated_at` string, date-time — Last update timestamp
  - `expires_at` string, date-time, required — Token expiration timestamp

## Other responses

- `400` — Bad request - missing required fields
- `401` — Unauthorized - invalid credentials
- `405` — Method not allowed

## Changes

- **2026-07-21** `ab7f39922bbe` — 1 info
  - added the optional property `user/language` to the response with the `200` status
- **2025-12-31** `e42f05599d8a` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/pierre-b/apis/notifuse-api/changes/api/user.rootSignin/post.md)

---

[API](https://skmtc.dev/pierre-b/apis/notifuse-api.md) · [All operations](https://skmtc.dev/pierre-b/apis/notifuse-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/pierre-b/notifuse-api/revisions/d26605f2fc47/schema)
