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.

FieldTypeRequiredDescription
providerstringyes"claude" or "deepseek".
api_keystringyesThe 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.

Errors400 if api_key is empty.

POST /api/removeAgentKey#

Clear your stored key for a provider.

FieldTypeRequiredDescription
providerstringyesProvider 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.

FieldTypeRequiredDescription
chat_idUUIDyesGroup 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.

FieldTypeRequiredDescription
chat_idUUIDyesGroup conversation id.
agent_usernamestringyesAgent to add — must be owned by the caller.
always_onbooleannotrue 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 }.

Errors403 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.

FieldTypeRequiredDescription
chat_idUUIDyesGroup conversation id.
agent_usernamestringyesAgent 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.

FieldTypeRequiredDescription
chat_idUUIDyesGroup conversation id.
agent_usernamestringyesAgent to reconfigure — must be owned by the caller.
always_onbooleanyesNew 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.