# Authentication

Public API requests use scoped bearer tokens created by a System Admin in
HollyHR.

```text
Authorization: Bearer hhr_live_...
Accept: application/json
```

## Create an API key

1. Sign in as a System Admin.
2. Open **Settings > API**.
3. Choose a clear key name.
4. Select only the scopes the integration needs.
5. Create the key and copy the token immediately.

The token is shown once. HollyHR stores only a hash, so the full token cannot be
retrieved later. Revoke the key and create a replacement if a token is lost or
shared too widely.

## Scopes

| Scope                    | Allows                                                                                                     |
| ------------------------ | ---------------------------------------------------------------------------------------------------------- |
| `organisation:read`      | Read safe organisation account details and active organisation locations.                                  |
| `people:read`            | Read people directory projections.                                                                         |
| `people:personal:read`   | Read one person's elevated personal profile fields.                                                        |
| `people:avatar:read`     | Read one person's short-lived profile-avatar URL and image metadata.                                       |
| `people:write`           | Create people, update safe setup/employment fields, and run safe lifecycle actions.                        |
| `org_units:read`         | Read org units, hierarchy, provider ids, and organisation-structure links.                                 |
| `org_units:write`        | Create, update, archive, and reactivate org units. Does not assign people or reporting lines.              |
| `reference:read`         | Read lookup dictionaries and reference values.                                                             |
| `time_off:read`          | Read time-off records, person balance metrics, sickness/other-leave aggregate totals, and public holidays. |
| `time_off:write`         | Create time off and update/cancel pending time-off records.                                                |
| `time_off:balance:write` | Create audited manual time-off balance adjustments.                                                        |
| `time_off:config:write`  | Create, update, and archive time-off categories, and update safe time-off settings.                        |
| `documents:read`         | Read document metadata only.                                                                               |
| `working_patterns:read`  | Read working-pattern templates and weekly or multi-week pattern days.                                      |
| `working_patterns:write` | Create, update, archive, and delete working-pattern templates.                                             |
| `provider_mappings:read` | Read active provider/remote ID mappings. Also requires the relevant resource read scope.                   |
| `payroll_exports:read`   | Read the elevated payroll readiness export package and sensitive presence/gap signals.                     |
| `webhooks:manage`        | Create, update, test, rotate, and delete webhook endpoint subscriptions.                                   |

Scopes are additive. A key without the required scope receives
`permission_denied`.

Write scopes do not expose sensitive fields. The beta people and time-off write
surfaces do not accept compensation, bank, tax or government
identifiers, demographics, emergency contacts, free-text employment notes,
time-off notes or reasons, approval/rejection decisions, edits to
approved/taken/cancelled time-off records, document bytes, avatar bytes, or
implicit people reassignment payloads. Date of birth and home contact/address
fields require the separate `people:personal:read` scope.
The payroll readiness export returns safe operational fields and elevated
presence flags for sensitive payroll-readiness gaps. It does not expose raw
salary, bank, NI/tax/government-id, date-of-birth, or home-address values.

## Environment and actor context

Use `GET /me` to inspect the authenticated key context. The response includes:

- `environment.type: "live"` and `environment.sandbox: false` for the current
  beta API.
- `actor.type: "api_key"` and the authenticated `key_id`.

API keys act for the organisation. They do not impersonate the System Admin who
created the key, and they do not act as a named employee. Public API writes and
elevated people reads are audited as API-key actors with safe key metadata. A
separate sandbox/test key environment is future work and is not hidden behind
the live beta token prefix.
Use [Environments and Testing](/environments-testing) for safe integration test
guidance.

## Key hygiene

- Use one key per integration.
- Revoke keys that are no longer used.
- Store tokens in a secrets manager or encrypted environment variable.
- Never put API tokens in browser code, logs, support tickets, or screenshots.
