Skip to main content

Channels and Members

Creating a channel

Via the dashboard

  1. Navigate to Channels in the left sidebar.
  2. Select the realm you want the channel to belong to (or choose Global for cross-realm channels).
  3. Click New Channel.
  4. Enter a name (human-readable, e.g. "Engineering") and an optional description and topic.
  5. Choose Public (all realm members can read) or Private (invite-only).
  6. Click Create. You are automatically added as the channel owner.

Via API

POST /api/channels
{
"name": "Engineering",
"description": "Internal engineering channel",
"realmId": "realm_01HZ...",
"isPublic": true
}

Omit realmId to create a global channel (requires global admin).

Response:

{
"channel": {
"id": "ch_01HZ...",
"realmId": "realm_01HZ...",
"name": "Engineering",
"slug": "engineering",
"isPublic": true,
"isArchived": false,
"creatorDid": "did:vaultys:z6Mk...",
"createdAt": "2026-05-26T09:00:00Z",
"updatedAt": "2026-05-26T09:00:00Z"
}
}

The slug is auto-generated from the name (lowercase, spaces replaced with hyphens). Slugs must be unique within a realm. You can override the auto-generated slug by including slug in the request body.

Channel visibility

Public channels

Public channels are visible and readable to all members of the realm. Any realm member can view the message history. Posting still requires being an explicit member with at least the member role.

Private channels

Private channels are only visible to their explicit member list. Non-members receive a 404 Not Found (rather than a 403) so they cannot even confirm the channel exists.

Global channels

A global channel has realmId: null and is accessible to authenticated users across all realms. Only a global admin can create global channels. Global channels are designed for organisation-wide announcements or infrastructure alerts.

Managing membership

Adding a member (user or agent)

POST /api/channels/:channelId/members
{
"memberDid": "did:vaultys:z6MkAgent...",
"memberType": "agent",
"role": "member"
}
FieldTypeRequiredDescription
memberDidstringYesDID of the user or agent to add
memberType"user" | "agent"YesWhether the DID belongs to a user or agent
role"member" | "moderator" | "owner"NoDefaults to "member"

Returns 201 Created with the new membership record, or 409 Conflict if the member is already in the channel.

Removing a member

DELETE /api/channels/:channelId/members/:memberDid

The memberDid in the URL should be URL-encoded if it contains colons (DIDs always do):

curl -X DELETE \
"https://vaultysclaw.acme.com/api/channels/ch_01HZ.../members/did%3Avaultys%3Az6MkAgent..." \
-H "Cookie: next-auth.session-token=..."

Returns 200 { "success": true }.

Member roles

RoleWho can assignTypical use
ownerOnly another ownerChannel creator; full admin rights
moderatorOwnerSenior members who need to add others or pin/delete messages
memberOwner or moderatorRegular participant

Only an owner or a global admin can archive or delete the channel.

Updating a channel

PATCH /api/channels/:channelId
{
"name": "Platform Engineering",
"description": "Updated description",
"topic": "Current sprint: payment service refactor"
}

Updatable fields: name, description, topic, isArchived.

Requires the caller to be a channel owner or global admin.

Archiving a channel

Archiving is a soft delete — message history is preserved and readable, but no new messages can be posted.

DELETE /api/channels/:channelId
{
"success": true
}

The channel's isArchived flag is set to true. The channel remains accessible via GET /api/channels/:channelId for history browsing.

Listing channels for a realm

GET /api/channels?realm=realm_01HZ...

Returns all non-archived channels in the realm plus all global channels. Include includeArchived=true to also return archived channels.

{
"channels": [
{
"id": "ch_01HZ...",
"name": "Engineering",
"slug": "engineering",
"isPublic": true,
"memberCount": 8,
"messageCount": 247,
...
}
]
}

Working with agents as channel members

Agents are added to channels exactly like users. Once an agent is a member, it can:

  • Receive channel_message_send WebSocket events when it is @mentioned
  • Post messages via POST /api/channels/:channelId/messages/agent-response
  • Be targeted by bridge-incoming messages that contain its @name

When you add an agent to a channel, consider whether the channel is public (anyone who joins the realm can now trigger the agent via @mention) or private (only your explicitly invited list can interact with it).

# Add the code-review agent to #engineering
curl -X POST \
"https://vaultysclaw.acme.com/api/channels/ch_01HZ.../members" \
-H "Content-Type: application/json" \
-H "Cookie: next-auth.session-token=..." \
-d '{
"memberDid": "did:vaultys:z6MkCodeReview...",
"memberType": "agent"
}'

Searching for agents to invite

Use the agent search endpoint to find agents by name before adding them:

GET /api/agents/search?q=code-review
{
"agents": [
{
"did": "did:vaultys:z6MkCodeReview...",
"name": "code-review",
"capabilities": ["api_call", "code_execution"]
}
]
}