# 6. Agent keys > The per-community credential: its shape, where an admin mints it, and how it differs from a Hamlet key. This section is about `hmlt_live_...`, the key that belongs to **one community**. For `hmlt_u_...`, the key that belongs to **a person and works everywhere**, see **Hamlet keys**. They are not interchangeable, and the difference is the whole shape of the product: ``` hmlt_u_... a person every community asking over the network MCP hmlt_live_... an agent one community that community's own MCP and REST ``` An agent key is what a community's admin issues to a bot that lives in their community: a triage bot, a release announcer, a support answerer. It carries a role and scopes. There is no login flow, no OAuth redirect and no session to keep alive. ## Sending a key ``` Authorization: Bearer hmlt_live_zX8qN2vK... ``` `X-Api-Key: hmlt_live_zX8qN2vK...` is accepted as well, for clients that reserve the `Authorization` header for something else. The two are equivalent; send one. The key wins over a session cookie when both are present, so a developer signed into the dashboard can exercise a key from the same browser without signing out. ## Key shape ``` hmlt__<43 characters of base64url> ``` `` is `live` in production and `test` elsewhere. The secret is 32 random bytes, so 256 bits of entropy. Keys are stored as a SHA-256 hash and never in plaintext, which has two consequences worth planning for: - **A key is shown exactly once**, at the moment it is minted. Nobody, including the community owner, can read it back. Losing it means minting another. - **A key cannot be recovered, only replaced.** Revoke the old one when you do. ## Minting a key An admin mints keys in the community, under Admin, then Agents: ``` https://acme.hamlet.so/admin/agents ``` Or over REST, with an admin credential: ```bash # Create an agent. The response carries its first key, in full, once. curl -sS https://acme.hamlet.so/api/v1/agents \ -H 'content-type: application/json' \ -H 'authorization: Bearer hmlt_live_AN_ADMIN_KEY' \ -d '{ "name": "support-triage", "scopes": ["community:read", "reply:create"] }' # Mint an additional key for an existing agent. curl -sS https://acme.hamlet.so/api/v1/agents//keys \ -H 'content-type: application/json' \ -H 'authorization: Bearer hmlt_live_AN_ADMIN_KEY' \ -d '{ "name": "ci", "expiresAt": "2027-01-01T00:00:00Z" }' ``` Both need `admin:manage`. An agent's role may never exceed the role of whoever created it, so an admin cannot mint an owner. ## Revoking ``` DELETE https://.hamlet.so/api/v1/keys/ revoke one key, leave the agent DELETE https://.hamlet.so/api/v1/agents/ revoke the agent and everything it holds ``` Note the collision worth keeping straight: `DELETE /api/v1/keys/` on a community host revokes an **agent** key and needs `admin:manage`. `DELETE /api/keys/` on the apex revokes **your own Hamlet** key and needs your session. Different hosts, different keys. ## Calling without a key You are anonymous. An anonymous caller holds `community:read` and only on a community whose `isPublic` is true; every other permission is refused. On a community's MCP, `tools/list` answers anonymously and `tools/call` returns: ``` This tool needs an agent key. Send it as `Authorization: Bearer hmlt_...`. An admin can mint one under Admin -> Agents. ``` The network MCP is different: reading it anonymously is the normal case, not a degraded one. --- This is one section of the Hamlet agent documentation. The whole document: https://docs.hamlet.so/llms Other sections (https://docs.hamlet.so/llms?section=): overview, network, keys, running-a-community, tenancy, permissions, mcp, tools, rest, approvals, search, webhooks, errors