# API Keys

API Keys authenticate requests to Sentinel's HTTP API — every API interaction requires one, including the widget fetching a challenge. Each key is created under a [Security Group](/docs/sentinel/configure/security-groups/) and inherits that group's access level and rules.

## Key and secret

A key has two parts:

- **The key itself** — a public identifier in the form `key_...`. This is what the widget uses in its `challenge` URL (`?apiKey=key_...`).
- **The secret** — a cryptographic value used to verify requests, configurable (and rotatable) after the key is created. See [Server Integration](/docs/integration/server/) for how your server uses it to verify submissions.

> **Warning:**
>
> For **Public** and **Restricted** access-level keys, never expose the secret in URLs or headers sent from the browser — only the public key belongs client-side.

## Configuration settings

- **Name** — a descriptive label (e.g. a project or website name) to identify the key.
- **Security Group** — determines the key's permissions and access rules; see [Security Groups](/docs/sentinel/configure/security-groups/).
- **Secret** — the cryptographic verification value, configurable after the key is created.
- **Request Logs** — logging level for requests made with this key: verification endpoints only, all requests, or disabled (which also disables analytics for the key).

## Usage, by access level

Always include your API key on every HTTP API request. How you send it depends on the key's Security Group access level.

### Public and Restricted access

Either form works, and both behave the same way:

- As a URL parameter: `?apiKey=key_...`
- As a header: `Authorization: Bearer key_...`

This is what the widget uses — `challenge="https://sentinel.example.com/v1/challenge?apiKey=key_..."`. Never attach the secret to a Public or Restricted request; only the key itself is meant to be client-side.

### Full access (administrative)

Full-access endpoints require HTTP Basic authentication instead, combining the key ID and secret:

```
Authorization: Basic ${base64(apiKeyId + ':' + apiKeySecret)}
```

```bash
curl https://sentinel.example.com/v1/some-admin-endpoint \
-u "key_...:your-secret"
```

Because this sends the secret on every request, only call Full-access endpoints from a trusted backend — never from the browser.

## Related

- **[Security Groups](/docs/sentinel/configure/security-groups/)** — where a key's access level and rules come from.
- **[Widget Integration](/docs/integration/widget/)** — using a Public key in the widget's `challenge` attribute.
- **[Server Integration](/docs/integration/server/)** — using the secret to verify submissions server-side.
