# How API Authentication and Rate Limiting Work in Uptime Kuma

> Discover how Uptime Kuma secures its API with keys and rate limiting. Protect your service from abuse with effective authentication strategies.

- Repository: [Louis Lam/uptime-kuma](https://github.com/louislam/uptime-kuma)
- Tags: internals
- Published: 2026-02-28

---

**Uptime Kuma protects its HTTP API using API keys (or basic auth fallback) and enforces per-endpoint rate limits via token-bucket limiters to prevent abuse.**

The `louislam/uptime-kuma` repository implements a dual-layer security model that combines flexible authentication with aggressive throttling. Understanding how [`server/auth.js`](https://github.com/louislam/uptime-kuma/blob/main/server/auth.js) and [`server/rate-limiter.js`](https://github.com/louislam/uptime-kuma/blob/main/server/rate-limiter.js) interact is essential for integrating monitoring data safely into your infrastructure. This article explains the exact mechanisms governing credential verification and request throttling as implemented in the source code.

## API Authentication Architecture

### Authentication Flow and Middleware

All API routes in Uptime Kuma are protected by the `apiAuth` middleware defined in [`server/auth.js`](https://github.com/louislam/uptime-kuma/blob/main/server/auth.js). The middleware first consults runtime settings to determine which authentication mode is active:

1. **Auth disabled mode** – When `Settings.get("disableAuth")` returns `true`, the middleware bypasses all checks entirely (useful for isolated testing environments).
2. **API key mode** – When `apiKeysEnabled` is `true`, the system invokes `apiAuthorizer` (lines 79-96 in [`server/auth.js`](https://github.com/louislam/uptime-kuma/blob/main/server/auth.js)).
3. **Basic auth fallback** – If API keys are disabled, the system falls back to `userAuthorizer` (lines 106-122 in [`server/auth.js`](https://github.com/louislam/uptime-kuma/blob/main/server/auth.js)) for traditional username/password validation.

Both authorizers integrate with the rate limiting system before performing credential verification. If the respective rate limiter denies the request, authentication aborts immediately and logs a warning.

### API Key Format and Verification

Uptime Kuma API keys follow a strict format: `uk<ID>_<secret>`. The prefix `uk` identifies the key type, the numeric segment between the prefix and the first underscore represents the database ID, and the trailing segment is the clear-text secret users must protect.

The verification logic resides in `verifyAPIKey` (lines 41-63 in [`server/auth.js`](https://github.com/louislam/uptime-kuma/blob/main/server/auth.js)). This function:

- Extracts the ID from the key format
- Queries the `api_key` table for the stored bcrypt hash
- Validates the key's expiry date and active status
- Compares the supplied clear-text secret against the stored hash using `passwordHash`

When authentication succeeds, the request proceeds to the route handler. On failure, the server returns **401 Unauthorized**. Notably, rate limiter tokens are **not** consumed for failed API key validations—only successful checks decrement the bucket.

### Basic Auth Fallback

When API keys are disabled, `userAuthorizer` handles credential validation using the same HTTP Basic Auth mechanism but validates against user account passwords stored in the database. This path uses `loginRateLimiter` rather than `apiRateLimiter`, applying stricter throttling appropriate for interactive login attempts.

## Rate Limiting Implementation

### Token Bucket Configuration

Uptime Kuma leverages the `limiter` NPM package to implement token-bucket rate limiting. The [`server/rate-limiter.js`](https://github.com/louislam/uptime-kuma/blob/main/server/rate-limiter.js) file instantiates three independent limiters wrapped in a custom `KumaRateLimiter` class that logs remaining tokens via its `pass()` method (lines 25-38).

Each limiter maintains a token count that decrements with every permitted request. When the count goes negative, the limiter returns `false` and the calling authorizer rejects the request.

### Rate Limit Thresholds

The system enforces distinct thresholds for different authentication surfaces:

- **`apiRateLimiter`**: 60 requests per minute for API key authentication (`apiAuthorizer`)
- **`loginRateLimiter`**: 20 requests per minute for username/password login attempts (`userAuthorizer`)
- **`twoFaRateLimiter`**: 30 requests per minute for two-factor authentication verification (handled in [`2fa.js`](https://github.com/louislam/uptime-kuma/blob/main/2fa.js))

These limits apply *before* credential verification occurs, protecting the bcrypt hashing operations from brute-force load.

## Runtime Configuration Settings

Authentication behavior is controlled through the `Settings` class in [`server/settings.js`](https://github.com/louislam/uptime-kuma/blob/main/server/settings.js), which provides a cached key/value store with a 60-second TTL:

- **`disableAuth`**: When set to `true`, all authentication checks are skipped across the entire application
- **`apiKeysEnabled`**: Toggles between API key mode and traditional basic authentication

Both settings persist in the `setting` database table and are queried by `apiAuth` on every request to determine which authorization path to execute.

## Practical Usage Examples

### Creating API Keys

Generate keys through the web interface:

1. Log in to the Uptime Kuma dashboard
2. Navigate to **Settings → API Keys**
3. Click **Add New Key** to generate a key like `uk12_7e4a9b...`
4. Copy the key immediately—the clear-text secret cannot be retrieved later

The UI stores only the bcrypt hash in the `api_key` table via the socket handler in [`server/socket-handlers/api-key-socket-handler.js`](https://github.com/louislam/uptime-kuma/blob/main/server/socket-handlers/api-key-socket-handler.js).

### Authenticating Requests with cURL

Pass the API key as the password in HTTP Basic Auth. The username field is ignored but conventionally set to `api`:

```bash
curl -u api:'uk12_7e4a9b...' \
     -H "Accept: application/json" \
     https://uptime.kuma.example/api/monitors

```

For automated scripts, include the key in the Authorization header:

```bash
curl -H "Authorization: Basic $(echo -n 'api:uk12_7e4a9b...' | base64)" \
     https://uptime.kuma.example/api/monitors

```

### Handling Rate Limit Responses

When exceeding the 60 requests/minute threshold for API keys, the `apiRateLimiter` causes `apiAuthorizer` to return **401 Unauthorized** (or **429 Too Many Requests** in some edge cases). Test rate limiting behavior with a loop:

```bash
for i in {1..65}; do
  curl -s -o /dev/null -w "%{http_code}\n" \
       -u api:'uk12_7e4a9b...' \
       https://uptime.kuma.example/api/monitors
done

```

Requests 61 through 65 will fail with authentication errors once the token bucket empties.

## Summary

- **API authentication** in Uptime Kuma uses the `apiAuth` middleware to choose between API key verification (`apiAuthorizer`) and basic auth (`userAuthorizer`) based on the `apiKeysEnabled` setting.
- **API keys** follow the format `uk<ID>_<secret>` and are verified against bcrypt hashes stored in the database via `verifyAPIKey` in [`server/auth.js`](https://github.com/louislam/uptime-kuma/blob/main/server/auth.js).
- **Rate limiting** employs token-bucket limiters (`apiRateLimiter`, `loginRateLimiter`, `twoFaRateLimiter`) that enforce thresholds of 60, 20, and 30 requests per minute respectively.
- **Runtime settings** (`disableAuth`, `apiKeysEnabled`) are cached for 60 seconds via [`server/settings.js`](https://github.com/louislam/uptime-kuma/blob/main/server/settings.js) to minimize database queries on every request.
- **Security sequencing** checks rate limits before performing expensive bcrypt hash comparisons, preventing CPU exhaustion attacks.

## Frequently Asked Questions

### What authentication methods does Uptime Kuma support?

Uptime Kuma supports two primary authentication methods: **API keys** (recommended for automation) and **HTTP Basic Auth** using username and password credentials. The active method is determined by the `apiKeysEnabled` runtime setting stored in [`server/settings.js`](https://github.com/louislam/uptime-kuma/blob/main/server/settings.js). When `disableAuth` is enabled, all authentication is bypassed for testing purposes.

### How does the API key format work in Uptime Kuma?

All API keys use the format `uk<ID>_<secret>`, where the numeric ID identifies the database record and the secret portion is user-provided. The server extracts the ID from between the `uk` prefix and the first underscore, then verifies the secret against a bcrypt hash stored in the `api_key` table using the `verifyAPIKey` function in [`server/auth.js`](https://github.com/louislam/uptime-kuma/blob/main/server/auth.js).

### What are the rate limits for API requests?

Uptime Kuma enforces three distinct rate limits via [`server/rate-limiter.js`](https://github.com/louislam/uptime-kuma/blob/main/server/rate-limiter.js): **60 requests per minute** for API key authentication (`apiRateLimiter`), **20 requests per minute** for username/password login attempts (`loginRateLimiter`), and **30 requests per minute** for 2FA verification (`twoFaRateLimiter`). These limits apply before credential validation to protect against brute-force attacks.

### How can I disable authentication for testing?

Set the `disableAuth` setting to `true` via the runtime configuration in [`server/settings.js`](https://github.com/louislam/uptime-kuma/blob/main/server/settings.js). When this flag is active, the `apiAuth` middleware in [`server/auth.js`](https://github.com/louislam/uptime-kuma/blob/main/server/auth.js) bypasses all credential checks, allowing unrestricted access to the API. This should only be used in isolated testing environments and never in production deployments.