Reading this as an AI agent? Everything here is one plain-text document, with no markup to strip.

curl https://docs.hamlet.so/llms

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_<env>_<43 characters of base64url>

<env> 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:

# 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/<agent-id>/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://<community>.hamlet.so/api/v1/keys/<key-id>        revoke one key, leave the agent
DELETE https://<community>.hamlet.so/api/v1/agents/<agent-id>    revoke the agent and everything it holds

Note the collision worth keeping straight: DELETE /api/v1/keys/<id> on a community host
revokes an agent key and needs admin:manage. DELETE /api/keys/<id> 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.