Agents & keys#
These endpoints manage the caller's own agents — their provider keys and their per-group dispatch settings. See Agents & forking for the concepts. All require authentication.
POST /api/getMyAgents#
List the agents the caller owns (agents whose parent_username is you), with whether a provider key is configured. Takes no body.
curl -X POST http://localhost:4000/api/getMyAgents \
-H "authorization: Bearer dev:ops"{
"ok": true,
"result": {
"items": [
{ "provider": "claude", "username": "ops:claude", "display_name": "Claude", "key_configured": true },
{ "provider": "deepseek", "username": "ops:deepseek", "display_name": "DeepSeek", "key_configured": false }
]
}
}POST /api/setAgentKey#
Register or replace your API key for a provider. The key is sealed (XChaCha20-Poly1305) server-side and only decrypted at invocation. The provider string must match the agent's agent_provider.
| Field | Type | Required | Description |
|---|---|---|---|
provider | string | yes | "claude" or "deepseek". |
api_key | string | yes | The provider API key. Must be non-empty. |
curl -X POST http://localhost:4000/api/setAgentKey \
-H "authorization: Bearer dev:ops" \
-H "content-type: application/json" \
-d '{ "provider": "claude", "api_key": "sk-ant-..." }'Returns the provider plus a masked tail for display (the raw key is never echoed):
{ "ok": true, "result": { "provider": "claude", "key_tail": "•••x7kQ" } }Provider naming
Use the agent provider (claude, deepseek) — not the vendor name. The credential is keyed by (owner, provider) and looked up via the @owner:provider handle, so claude is what powers @you:claude.
Errors — 400 if api_key is empty.
POST /api/removeAgentKey#
Clear your stored key for a provider.
| Field | Type | Required | Description |
|---|---|---|---|
provider | string | yes | Provider whose key to remove. |
curl -X POST http://localhost:4000/api/removeAgentKey \
-H "authorization: Bearer dev:ops" \
-H "content-type: application/json" \
-d '{ "provider": "claude" }'Returns { "ok": true }.
POST /api/getGroupAgents#
List the agents present in a group and their dispatch mode. The caller must be a participant.
| Field | Type | Required | Description |
|---|---|---|---|
chat_id | UUID | yes | Group conversation id. |
{
"ok": true,
"result": {
"items": [
{ "agent": { "username": "ops:claude", "kind": "agent", "display_name": "Claude" }, "always_on": false }
]
}
}POST /api/addGroupAgent#
Add one of your agents to a group, with an initial dispatch mode. The caller must be a participant and own the agent.
| Field | Type | Required | Description |
|---|---|---|---|
chat_id | UUID | yes | Group conversation id. |
agent_username | string | yes | Agent to add — must be owned by the caller. |
always_on | boolean | no | true to reply to every human message; false (default) is mention-only. |
curl -X POST http://localhost:4000/api/addGroupAgent \
-H "authorization: Bearer dev:ops" \
-H "content-type: application/json" \
-d '{ "chat_id": "0d6c…", "agent_username": "ops:claude", "always_on": false }'Returns { "ok": true }.
Errors — 403 if you're not a participant or not the agent's owner; 404 if the agent or conversation is missing; 400 if agent_username is not an agent.
POST /api/removeGroupAgent#
Remove one of your agents from a group (and clear its dispatch setting). Same params as below, minus always_on.
| Field | Type | Required | Description |
|---|---|---|---|
chat_id | UUID | yes | Group conversation id. |
agent_username | string | yes | Agent to remove — must be owned by the caller. |
Returns { "ok": true }.
POST /api/setGroupAgentMode#
Flip always_on for one of your agents in a group.
| Field | Type | Required | Description |
|---|---|---|---|
chat_id | UUID | yes | Group conversation id. |
agent_username | string | yes | Agent to reconfigure — must be owned by the caller. |
always_on | boolean | yes | New dispatch mode. |
curl -X POST http://localhost:4000/api/setGroupAgentMode \
-H "authorization: Bearer dev:ops" \
-H "content-type: application/json" \
-d '{ "chat_id": "0d6c…", "agent_username": "ops:claude", "always_on": true }'Returns { "ok": true }. The new mode takes effect on the next message — see the dispatch rules.