Create, scope, and rotate the server-side keys used by your Agent integration.
An API key authenticates your server, not your visitors. It can mint short-lived browser tokens, authorize read-only public API requests, or do both, depending on the permissions you assign. The key itself never leaves your infrastructure and the browser never holds a long-lived credential.
Keys are managed per project in the dashboard. Workspace members can create keys and rename or revoke the keys they created. The workspace owner can rename or revoke any key. Anyone with access to the Agent can copy an active key.
Names are how you tell keys apart when it is time to rotate one. production-web and staging are useful; key 1 is not.
Select only what this server needs. The embed token endpoint needs auth_tokens:create; data integrations need the matching users:read, conversations:read, or runs:read permission.
Copy the key into your secret manager. New keys can also be copied later from the key table, but revoked keys and keys created before token copying was introduced cannot be retrieved.
HEROUI_AGENT_API_KEY=he_...
HEROUI_AGENT_ID=your_agent_idSend a message from the embed. If your endpoint can mint a token, the conversation connects. A rejected key surfaces as an authentication failure rather than a silent empty response.
Never prefix the key with NEXT_PUBLIC_ or reference it in client code. Any variable a bundler
can see ends up in your JavaScript, and a leaked key can exercise every permission assigned to it.
| Permission | Dashboard label | Allows |
|---|---|---|
auth_tokens:create | Connect the Agent to your app | Allow people to use this Agent in your app. |
users:read | View users | See the people who have used this Agent. |
conversations:read | View conversations | See conversations and messages between people and this Agent. |
runs:read | View runs | View this Agent's run history, including usage, latency, and tool activity. |
Use separate keys when services have different responsibilities. A backend that only exports run metrics, for example, needs runs:read but does not need access to users, conversations, or token minting.
Keys created before permissions were introduced retain only auth_tokens:create. They never
inherit read access to users, conversations, or runs automatically.
Minting a browser token requires auth_tokens:create and must happen inside your own server route:
import {createAuthToken} from "@heroui/agent/server";
export async function POST(request: Request) {
const {anonymousId, agentId} = await request.json();
if (agentId !== process.env.HEROUI_AGENT_ID) {
return Response.json({error: "Invalid agent"}, {status: 400});
}
return Response.json(
await createAuthToken({
apiKey: process.env.HEROUI_AGENT_API_KEY!,
identity: {id: anonymousId, type: "anonymous"},
agentId,
}),
{headers: {"Cache-Control": "no-store"}},
);
}See the Quickstart for the full setup and Identifying users for connecting tokens to signed-in people.
To query users, conversations, or runs from a server, see the HTTP API authentication guide.
The table shows each key's name, masked token, status, creator, and creation date. The full secret is encrypted at rest; only its prefix and last four characters appear until someone selects Copy.
| Action | Who can use it | Effect |
|---|---|---|
| Copy | Any workspace member with access to the Agent | Decrypts and copies an active, retrievable key |
| Rename | The key's creator, or the workspace owner | Changes the label only. The key keeps working |
| Delete | The key's creator, or the workspace owner | Revokes the key. Requires typing the key name to confirm |
Revoking is immediate and cannot be undone. Any server still presenting a revoked key can no longer mint tokens or call the public API, and existing conversations stop connecting once their current tokens expire.
Because a project can hold several active keys, rotation does not need downtime:
Rotate when someone with access leaves, when a key may have been exposed, or on whatever schedule your security policy sets.
Use a separate project — with its own keys — for staging. Sharing one project between environments means test conversations land in the same monitoring as production traffic.
Authentication fails after a deploy. Confirm the environment variable is present in the deployed environment, not only locally, and that the key has not been revoked.
A public API request returns 403 insufficient_scope. The key is valid but does not have the permission required by that endpoint. Create a replacement with the minimum required read permission.
Tokens are minted but the agent is rejected. The agentId your endpoint validates must match the agent the key belongs to. A key from one agent cannot mint tokens for another.
The key leaked. Revoke it immediately and create a replacement. Revocation takes effect at once; there is no need to wait for a deploy to finish first.