Authentication
Keys and scopes.
Every request carries a bearer token. The prefix decides whether you act as a person or as a bot, and the scopes on the key decide what you're allowed to touch. You create keys in the app and copy them once.
The header
Send the key as a bearer token on every request:
curl /api/v1/workspaces//me \
-H "Authorization: Bearer " GET /me takes no scope and returns the identity behind the key,
either a user or a bot principal. It's the quickest
way to confirm a key is live and pointed at the right workspace.
Three kinds of key
Two are bots with their own identity in the workspace; you grant them access
and add them where they should take part. Both use the same
threa_bk_ prefix, and what differs is whether the bot is yours or
the workspace's. The third carries your own identity and access.
Personal bot key threa_bk_
A bot you own, with its own identity in the workspace: your local Pi, an OpenClaw, an agent on your laptop. You add it to the streams it should see, and it acts as itself, not as you.
Workspace bot key threa_bk_
A shared bot, created by an admin, that belongs to the workspace rather than a person: a GitHub notifier, a CI poster, an integration. It has its own identity and is added to the streams it posts in.
Personal access key threa_uk_
Carries your identity and your access, so it can never do more than you can; if your role narrows later, so does the key. Messages it sends are attributed to you, flagged as sent via the API.
Creating a key
A personal access key is created under
Settings → API keys: name it, pick scopes, and copy the
threa_uk_… value once (up to 25 per person).
A bot key is created from a bot's own settings. Make the bot
first (a personal bot in your settings, or a shared bot if you're an admin),
then mint a threa_bk_… key on it (up to 25 per bot), give it the
scopes it needs, and add the bot to the streams it should see.
Keep scopes as narrow as the job allows. You can edit them later, and a narrow key fails safe. The table below lists what each one unlocks.
Scopes
These are the scopes a key can carry. Workspace-admin powers (managing members, creating shared bots, owning the workspace) are deliberately not grantable to API keys.
| Scope | Grants |
|---|---|
| messages:read | Read messages in streams you can access |
| messages:write | Send, edit, and delete messages your key created |
| messages:search | Search messages across the workspace |
| streams:read | List and read streams and their members |
| users:read | List and search workspace users |
| memos:read | Search memos and read their source messages |
| attachments:read | Search attachments and read extracted text |
| attachments:write | Upload attachments |
| bot-runtime:read | Read bot runtime presence and sessions |
| bot-runtime:write | Heartbeat a runtime and link sessions |
| bot-invocations:read | Read pending and claimed invocations |
| bot-invocations:write | Claim, step, complete, and fail invocations |
What a missing scope looks like
A valid key missing the required scope returns 404, the same
response as a resource that isn't there, so the API never confirms something
exists to a caller that can't access it. A missing or invalid key returns
401. See Operations
for the full error shape.