Comments
Endpoints for collaborating on an Assistant through comments.
Both routes are gated by ai.verify (AI must be enabled on the tenant AND the
caller must have AI access). The Assistant is resolved through assistant.lookup
(the read_access model scope), so an Assistant the caller may not see answers
404. Adding a comment additionally requires permission.assistant.chat, whose
driver is simply the caller's ai credential: if you can chat with the
Assistant you can comment on it, so no extra share or owner permission is needed.
GET /api/assistants/{id}/comments
List the top-level comments on an Assistant.
Authentication: Required (AI access via ai.verify)
Pre-blocks: assistant.lookup
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
sort | string | -createdAt | Sort order |
limit | integer | - | Maximum number of comments to return |
Response:
A HAL collection under _embedded["inf:comment"], filtered to top-level
comments (parentId is null) and sorted by -createdAt. Each embedded comment
carries an inf:comments link to its replies (./replies) and embeds the author
as inf:user. The stored comment text is in the message field.
{
"_links": {
"self": {
"href": "https://informer.example.com/api/assistants/00000000-0000-4000-8000-000000000001/comments?sort=-createdAt&limit=0"
}
},
"start": 0,
"count": 1,
"total": 1,
"_embedded": {
"inf:comment": [
{
"_links": {
"self": {
"href": "https://informer.example.com/api/comments/00000000-0000-4000-8000-000000000002"
},
"inf:comments": {
"href": "https://informer.example.com/api/comments/00000000-0000-4000-8000-000000000002/replies"
}
},
"permissions": {
"edit": true,
"delete": true
},
"id": "00000000-0000-4000-8000-000000000002",
"message": "Should we add a skill for quarterly forecasting?",
"public": false,
"userId": "admin",
"datasetId": null,
"datasourceId": null,
"reportId": null,
"queryId": null,
"teamId": null,
"jobId": null,
"templateId": null,
"assistantId": "00000000-0000-4000-8000-000000000001",
"libraryId": null,
"mentions": null,
"createdAt": "2026-01-15T16:20:00.000Z",
"updatedAt": "2026-01-15T16:20:00.000Z",
"tenant": "acme",
"parentId": null,
"_embedded": {
"inf:user": {
"_links": {
"self": {
"href": "https://informer.example.com/api/users/admin"
},
"inf:memberships": {
"href": "https://informer.example.com/api/users/admin/memberships"
},
"inf:avatar-upload": {
"href": "https://informer.example.com/api/users/admin/_upload/{uploadId}/avatar-upload",
"templated": true
},
"inf:password": {
"href": "https://informer.example.com/api/users/admin/password"
},
"inf:feed": {
"href": "https://informer.example.com/api/users/admin/feed"
},
"inf:viewed-feed": {
"href": "https://informer.example.com/api/users/admin/_markFeedViewed"
},
"inf:superuser": {
"href": "https://informer.example.com/api/users/admin/superuser"
}
},
"permissions": {
"changeDomain": false,
"changeProfile": true,
"changePassword": true,
"delete": false,
"edit": true,
"reassign": true,
"superuser": true,
"enable": true,
"changeTheme": true,
"lock": true,
"setGlobalPermissions": true,
"manageLogin": true
},
"domain": "local",
"username": "admin",
"displayName": "acme Administrator",
"familyName": "Administrator",
"givenName": "acme",
"middleName": null,
"email": null,
"data": null,
"superuser": true,
"timezone": "America/New_York",
"settings": {
"log": {
"log": false,
"info": false,
"warn": false,
"debug": false,
"error": true,
"remote": false
}
},
"enabled": true,
"source": null,
"sourceId": null,
"lastViewedFeed": null,
"tenant": "acme",
"globalPermissions": {
"ai": false,
"jobCreation": true,
"viewAllTeams": true,
"viewAllUsers": true,
"painlessScriptCreation": true
},
"userFields": {},
"locked": false,
"lockedAt": null,
"loginAttempts": 0,
"passwordSetAt": "2026-01-15T16:20:00.000Z",
"passwordExpiresAt": "2026-01-15T16:20:00.000Z",
"forgotPasswordRequestTime": null,
"mfa": null,
"mfaConfig": {},
"aiMessage": null,
"aiConsent": false,
"hasSharedDatasources": false,
"createdAt": "2026-01-15T16:20:00.000Z",
"updatedAt": "2026-01-15T16:20:00.000Z",
"initials": "EA",
"colorIndex": 4,
"avatarColor": {
"background": "#81C784",
"text": "#1B5E20"
},
"managesPassword": true
}
}
}
]
}
}
POST /api/assistants/{id}/comments
Add a comment to an Assistant.
Authentication: Required (AI access via ai.verify)
Pre-blocks: assistant.lookup, permission.assistant.chat
Request Body:
The payload is stripUnknown, so unrecognized fields are dropped rather than
rejected.
| Field | Type | Required | Description |
|---|---|---|---|
message | string | Yes | Comment text |
The comment text goes in message, not comment. The author (userId) is
server-derived from the authenticated caller; it is not a client-supplied field.
Example Request:
{
"message": "This assistant needs better instructions for handling edge cases."
}
Response:
Responds 201 Created with a Location header. The body is the raw Comment row
(id, message, public defaulting to false, userId, assistantId,
parentId, mentions, and timestamps); it is not HAL-shaped and does not inline
a user object.
{
"message": "This assistant needs better instructions for handling edge cases."
}
{
"_links": {
"self": {
"href": "https://informer.example.com/api/comments/00000000-0000-4000-8000-000000000002"
}
},
"permissions": {
"edit": true,
"delete": true
},
"id": "00000000-0000-4000-8000-000000000002",
"public": false,
"tenant": "acme",
"message": "This assistant needs better instructions for handling edge cases.",
"assistantId": "00000000-0000-4000-8000-000000000001",
"userId": "admin",
"updatedAt": "2026-01-15T16:20:00.000Z",
"createdAt": "2026-01-15T16:20:00.000Z",
"mentions": null,
"teamId": null,
"_altid": null,
"datasetId": null,
"datasourceId": null,
"reportId": null,
"queryId": null,
"jobId": null,
"parentId": null,
"templateId": null,
"libraryId": null
}
Use comments to document why certain instructions or skills were added, making future maintenance easier.