# Configuration

ushort accepts TOML and legacy JSON configuration files. TOML is preferred;
[`config.example.toml`](../config.example.toml) is the maintained reference.

```bash
ushort config.toml
ushort legacy-config.json
```

## Options

| Key | Required | Default | Description |
|---|---:|---:|---|
| `base_url` | yes | — | Public URL. Its path becomes the routing prefix. |
| `api_key` | yes | — | Secret used by list and delete operations. |
| `host` | no | `0.0.0.0` | Bind address. |
| `port` | no | `8080` | Bind port. |
| `db_path` | no | `data/urlshort.db` | SQLite database path. |
| `retention_days` | no | `0` | Default lifetime for new URLs; zero never expires. |
| `min_short_length` | no | `6` | Initial generated code length. |
| `max_short_length` | no | `32` | Maximum generated and accepted code length. |
| `max_url_length` | no | `2048` | Maximum original URL length. |
| `max_retention_days` | no | `3650` | Maximum per-URL retention value. |
| `rate_limit_requests` | no | `60` | Requests allowed per client/window. |
| `rate_limit_window` | no | `60` | Sliding-window length in seconds. |

The legacy `short_length` option remains an alias for `min_short_length`.
The removed legacy `production` key is ignored when present; ushort always
serves its embedded frontend and static assets.

## Public URL layouts

The same binary supports both common reverse-proxy layouts:

- `base_url = "https://s.example.com"` serves everything at the subdomain
  root and produces URLs such as `https://s.example.com/aB3xYz`.
- `base_url = "https://example.com/go/links"` routes only under `/go/links`
  and produces `https://example.com/go/links/aB3xYz`.

A trailing slash on `base_url` is accepted and normalized. Requests outside a
configured non-empty path prefix return 404.

Keep real API keys only in the ignored deployment `config.toml`. Never commit
them or include them in a container image.
