Knowledge Namespaces
Knowledge namespaces are named, visibility-controlled records for organizing knowledge in an account. Every list, get, update, and delete enforces the namespace's declared visibility.
Current limitation
Namespaces are not yet a retrieval scope: AI retrieval does not search by namespace, and knowledge contexts cannot be assigned to a namespace. Use workspace files and project knowledge to scope what the AI can use. See Current limitations.
Base path: /api/v1/accounts/{accountId}/knowledge-namespaces
Authentication: JWT Bearer token
Visibility Levels
| Level | Who can see, update, or delete it |
|---|---|
private | Only the creator |
workspace | Members who can open the namespace's workspace (default) |
account | All account members |
Roles never widen visibility: an owner or admin cannot see, rename, or delete another member's private namespace, or a workspace namespace in a workspace they cannot open. A namespace you cannot see returns the same 404 as one that does not exist.
List Namespaces
GET /accounts/{accountId}/knowledge-namespaces
Request
| Path Parameter | Description |
|---|---|
accountId | Account UUID |
| Query Parameter | Type | Description |
|---|---|---|
workspaceId | uuid | Narrow the visible namespaces to one workspace |
Response
Returns the namespaces the caller can see. The workspaceId filter only narrows that set; it never adds namespaces the caller cannot see.
Code Example
curl "https://api.chainabit.com/api/v1/accounts/$ACCOUNT_ID/knowledge-namespaces" \
-H "Authorization: Bearer $TOKEN"const response = await fetch(
`${BASE_URL}/accounts/${accountId}/knowledge-namespaces`,
{ headers: { Authorization: `Bearer ${TOKEN}` } }
);
const { data } = await response.json();import httpx
result = httpx.get(
f"{BASE_URL}/accounts/{account_id}/knowledge-namespaces",
headers={"Authorization": f"Bearer {token}"},
).json()Get Namespace
GET /accounts/{accountId}/knowledge-namespaces/{id}
Request
| Path Parameter | Description |
|---|---|
accountId | Account UUID |
id | Namespace UUID |
Response
Returns a single namespace object if the caller can see it; otherwise 404.
Create Namespace
POST /accounts/{accountId}/knowledge-namespaces
Requires owner or admin role.
Request
| Path Parameter | Description |
|---|---|
accountId | Account UUID |
Request body:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Display name (max 120 chars) |
slug | string | Yes | URL-safe identifier [a-z0-9-]+, unique per account |
visibility | string | No | private | workspace | account (default: workspace) |
The body has no workspace field. A workspace or private namespace belongs to the workspace selected for the request (the x-workspace-id header); an account namespace belongs to no workspace. Unknown body fields are rejected. | retentionDays | integer | No | Retention period in days (1–3650). Recorded on the namespace; automatic purge is not implemented yet. |
Response
Returns the created namespace object.
Code Example
curl -X POST "https://api.chainabit.com/api/v1/accounts/$ACCOUNT_ID/knowledge-namespaces" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Engineering Docs",
"slug": "engineering-docs",
"visibility": "workspace",
"retentionDays": 365
}'const response = await fetch(
`${BASE_URL}/accounts/${accountId}/knowledge-namespaces`,
{
method: 'POST',
headers: {
Authorization: `Bearer ${TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'Engineering Docs',
slug: 'engineering-docs',
visibility: 'workspace',
retentionDays: 365,
}),
}
);httpx.post(
f"{BASE_URL}/accounts/{account_id}/knowledge-namespaces",
json={
"name": "Engineering Docs",
"slug": "engineering-docs",
"visibility": "workspace",
"retentionDays": 365,
},
headers={"Authorization": f"Bearer {token}"},
)Update Namespace
PATCH /accounts/{accountId}/knowledge-namespaces/{id}
Requires owner or admin role and a workspace context (x-workspace-id) that you can open. Slug cannot be changed after creation. You can only update a namespace you can see.
Request
| Path Parameter | Description |
|---|---|
accountId | Account UUID |
id | Namespace UUID |
Request body: all fields optional
| Field | Type | Description |
|---|---|---|
name | string | New display name |
visibility | string | private | workspace | account |
retentionDays | integer or null | New retention period; null to remove. Automatic purge is not implemented yet. |
Visibility changes:
- Changing to
accountremoves the namespace's workspace. - Changing to
workspaceorprivaterequires access to the namespace's workspace, or to the request's workspace if the namespace has none. - Only the creator can make a namespace
private.
Response
Returns the updated namespace object.
Delete Namespace
DELETE /accounts/{accountId}/knowledge-namespaces/{id}
Soft-deletes the namespace. Requires owner or admin role, and you can only delete a namespace you can see. Associated contexts are not deleted.
Request
| Path Parameter | Description |
|---|---|
accountId | Account UUID |
id | Namespace UUID |
Response
Namespace is soft-deleted. Associated contexts are not deleted.
Errors
| Status | Description |
|---|---|
400 | Invalid slug format (must match [a-z0-9-]+), or a workspace/private namespace without a workspace context |
403 | Caller does not have owner or admin role, cannot open the target workspace, or is not the creator when making a namespace private |
404 | Namespace not found, or not visible to the caller |
409 | Slug already exists in this account (including deleted namespaces) |
Current limitations
- Not a retrieval scope yet. AI retrieval does not search by namespace, and knowledge contexts cannot be assigned to a namespace.
- Retention is recorded, not enforced.
retentionDaysis stored and returned; no automatic purge runs. - Slugs are account-wide. A slug stays reserved after its namespace is deleted, and creating a namespace with a slug held by a namespace you cannot see still returns
409.