# API authentication

Use an organization-scoped Hoplite API key beginning with `hop_`.

Send it either as `X-Api-Key: hop_…` or `Authorization: Bearer hop_…`.

## Create a service account

Sign in as an owner or admin, select the team workspace, and open Settings → Workspace → API keys → Service accounts → Create service account. Enter a name, select permissions, and enter comma-separated Project IDs to restrict access. Leave Project IDs blank only for organization-wide access. Select Create account and save the one-time credential as HOPLITE_API_KEY in backend secret storage. See [factory setup](/docs/factory#before-running) for the required grants.

To find a project ID first, create a personal API key on the same settings page and call [List projects](/docs/api/listProjects), matching the project name and repository.

Service credentials begin with `hop_svc_`, expire after 90 days, and support rotation with up to 24 hours of overlap. Current grants, project allowlists, revocation, and disabled accounts are checked on every request.

Account administration requires a current owner/admin session; service credentials can inspect their own identity and rotate themselves. Credentials do not inherit a creator's personal entitlements.

Published permissions: `automation:create`, `automation:delete`, `automation:read`, `automation:run`, `automation:update`, `mcpServer:create`, `mcpServer:delete`, `mcpServer:read`, `mcpServer:update`, `modelKey:read`, `project:create`, `project:delete`, `project:read`, `project:update`, `repo:read`, `repo:update`, `thread:create`, `thread:read`, `thread:retry`, `thread:stop`, `thread:update`, `usage:read`, `webhook:create`, `webhook:delete`, `webhook:read`, `webhook:update`.

Send a stable Idempotency-Key on every service-account write and reuse the exact request when retrying. Receipts last at least seven days. A changed payload returns 409. Only validation rejections are replayed; other 4xx responses, such as 402, 404, 409 state conflicts and 429, can be retried under the same key. Retrying an uncertain outcome settles it from the resource the first request created, or dispatches again once Hoplite proves nothing was created. `409 operation_outcome_unknown` means neither could be established: inspect /api/operations/{id} and the resource before using a new key. One-time secrets are not returned on replay.

The API ingress limit is 600 requests per rolling 60-second window; individual credentials may have a lower limit. Honor `429` and `Retry-After`.