Internal notes
Team-only notes on posts, with mentions and reactions.
Set up the SDK client used in the examples
API key or Dashboard session:
import { UpVoiced } from '@upvoiced/sdk';
const apiKey = process.env['UPVOICED_API_KEY']; // uv_live_… (Settings → API keys)
const workspace = process.env['UPVOICED_WORKSPACE_ID']; // sent as X-Workspace
if (!apiKey || !workspace) throw new Error('Set UPVOICED_API_KEY and UPVOICED_WORKSPACE_ID.');
const upvoiced = new UpVoiced({ apiKey, workspace });curl examples read $UPVOICED_API_KEY and $UPVOICED_WORKSPACE_IDfrom your shell. MCP examples are the tools/call request an MCP client sends to the MCP server with the same API key.
GET/v1/posts/{id}/notes
Internal notes with mentions and reactions (operator-only)
| Name | Type | Required |
|---|---|---|
id | string (uuid) | Yes |
| Name | Type | Required |
|---|---|---|
x-workspace | string (uuid) | Yes |
Response 200: 13 fields
| Name | Type | Required |
|---|---|---|
items | array of object | Yes |
items[].id | string (uuid) | Yes |
items[].post_id | string (uuid) | Yes |
items[].operator_id | string (uuid) | Yes |
items[].body_md | string | Yes |
items[].mention_ids | array of string (uuid) | Yes |
items[].reactions | array of object | Yes |
items[].reactions[].emoji | string | Yes |
items[].reactions[].count | integervalue ≥ 0 | Yes |
items[].reactions[].operator_ids | array of string (uuid) | Yes |
items[].created_at | string (date-time) | Yes |
items[].updated_at | string (date-time) | Yes |
next_cursor | string | null | Yes |
Errors: 400, 401, 403, 404, 409, 413, 422, 429, 500, 503, all in the standard error shape.
curl 'https://api.upvoiced.com/v1/posts/0190f5e2-4c1d-7a3b-8c2d-5e6f7a8b9c0d/notes' \
-H "Authorization: Bearer $UPVOICED_API_KEY" \
-H "X-Workspace: $UPVOICED_WORKSPACE_ID"const data = await upvoiced.get('/v1/posts/{id}/notes', { path: { id: '0190f5e2-4c1d-7a3b-8c2d-5e6f7a8b9c0d' } });No MCP tool for this operation. The MCP server covers the everyday reads and writes.
POST/v1/posts/{id}/notes
Add an internal note; mention_ids must be active members
| Name | Type | Required |
|---|---|---|
id | string (uuid) | Yes |
| Name | Type | Required |
|---|---|---|
x-workspace | string (uuid) | Yes |
idempotency-key | stringpattern ^[A-Za-z0-9_.:-]{8,128}$ | No |
| Name | Type | Required |
|---|---|---|
body_md | stringlength ≤ 10000 | Yes |
mention_ids | array of string (uuid)items ≤ 20default [] | No |
Response 201: 11 fields
| Name | Type | Required |
|---|---|---|
id | string (uuid) | Yes |
post_id | string (uuid) | Yes |
operator_id | string (uuid) | Yes |
body_md | string | Yes |
mention_ids | array of string (uuid) | Yes |
reactions | array of object | Yes |
reactions[].emoji | string | Yes |
reactions[].count | integervalue ≥ 0 | Yes |
reactions[].operator_ids | array of string (uuid) | Yes |
created_at | string (date-time) | Yes |
updated_at | string (date-time) | Yes |
Errors: 400, 401, 403, 404, 409, 413, 422, 429, 500, 503, all in the standard error shape.
curl -X POST 'https://api.upvoiced.com/v1/posts/0190f5e2-4c1d-7a3b-8c2d-5e6f7a8b9c0d/notes' \
-H "Authorization: Bearer $UPVOICED_API_KEY" \
-H "X-Workspace: $UPVOICED_WORKSPACE_ID" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"body_md": "It would help our night shift."
}'const data = await upvoiced.post('/v1/posts/{id}/notes', {
path: { id: '0190f5e2-4c1d-7a3b-8c2d-5e6f7a8b9c0d' },
body: { body_md: 'It would help our night shift.' },
});{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "add_note",
"arguments": {
"body_md": "It would help our night shift.",
"id": "0190f5e2-4c1d-7a3b-8c2d-5e6f7a8b9c0d"
}
}
}Tool add_note.
DELETE/v1/notes/{id}
Delete your own note (owners/admins: any note)
| Name | Type | Required |
|---|---|---|
id | string (uuid) | Yes |
| Name | Type | Required |
|---|---|---|
x-workspace | string (uuid) | Yes |
Response 200: 1 fields
| Name | Type | Required |
|---|---|---|
ok | true | Yes |
Errors: 400, 401, 403, 404, 409, 413, 422, 429, 500, 503, all in the standard error shape.
curl -X DELETE 'https://api.upvoiced.com/v1/notes/0190f5e2-4c1d-7a3b-8c2d-5e6f7a8b9c0d' \
-H "Authorization: Bearer $UPVOICED_API_KEY" \
-H "X-Workspace: $UPVOICED_WORKSPACE_ID"const data = await upvoiced.delete('/v1/notes/{id}', { path: { id: '0190f5e2-4c1d-7a3b-8c2d-5e6f7a8b9c0d' } });No MCP tool for this operation. The MCP server covers the everyday reads and writes.
POST/v1/notes/{id}/reactions
React to a note with an emoji (idempotent)
| Name | Type | Required |
|---|---|---|
id | string (uuid) | Yes |
| Name | Type | Required |
|---|---|---|
x-workspace | string (uuid) | Yes |
idempotency-key | stringpattern ^[A-Za-z0-9_.:-]{8,128}$ | No |
| Name | Type | Required |
|---|---|---|
emoji | stringlength 1–32 | Yes |
Response 200: 11 fields
| Name | Type | Required |
|---|---|---|
id | string (uuid) | Yes |
post_id | string (uuid) | Yes |
operator_id | string (uuid) | Yes |
body_md | string | Yes |
mention_ids | array of string (uuid) | Yes |
reactions | array of object | Yes |
reactions[].emoji | string | Yes |
reactions[].count | integervalue ≥ 0 | Yes |
reactions[].operator_ids | array of string (uuid) | Yes |
created_at | string (date-time) | Yes |
updated_at | string (date-time) | Yes |
Errors: 400, 401, 403, 404, 409, 413, 422, 429, 500, 503, all in the standard error shape.
curl -X POST 'https://api.upvoiced.com/v1/notes/0190f5e2-4c1d-7a3b-8c2d-5e6f7a8b9c0d/reactions' \
-H "Authorization: Bearer $UPVOICED_API_KEY" \
-H "X-Workspace: $UPVOICED_WORKSPACE_ID" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"emoji": "👍"
}'const data = await upvoiced.post('/v1/notes/{id}/reactions', {
path: { id: '0190f5e2-4c1d-7a3b-8c2d-5e6f7a8b9c0d' },
body: { emoji: '👍' },
});No MCP tool for this operation. The MCP server covers the everyday reads and writes.
DELETE/v1/notes/{id}/reactions
Remove your emoji reaction from a note (idempotent)
| Name | Type | Required |
|---|---|---|
id | string (uuid) | Yes |
| Name | Type | Required |
|---|---|---|
x-workspace | string (uuid) | Yes |
| Name | Type | Required |
|---|---|---|
emoji | stringlength 1–32 | Yes |
Response 200: 11 fields
| Name | Type | Required |
|---|---|---|
id | string (uuid) | Yes |
post_id | string (uuid) | Yes |
operator_id | string (uuid) | Yes |
body_md | string | Yes |
mention_ids | array of string (uuid) | Yes |
reactions | array of object | Yes |
reactions[].emoji | string | Yes |
reactions[].count | integervalue ≥ 0 | Yes |
reactions[].operator_ids | array of string (uuid) | Yes |
created_at | string (date-time) | Yes |
updated_at | string (date-time) | Yes |
Errors: 400, 401, 403, 404, 409, 413, 422, 429, 500, 503, all in the standard error shape.
curl -X DELETE 'https://api.upvoiced.com/v1/notes/0190f5e2-4c1d-7a3b-8c2d-5e6f7a8b9c0d/reactions' \
-H "Authorization: Bearer $UPVOICED_API_KEY" \
-H "X-Workspace: $UPVOICED_WORKSPACE_ID" \
-H "Content-Type: application/json" \
-d '{
"emoji": "👍"
}'const data = await upvoiced.delete('/v1/notes/{id}/reactions', {
path: { id: '0190f5e2-4c1d-7a3b-8c2d-5e6f7a8b9c0d' },
body: { emoji: '👍' },
});No MCP tool for this operation. The MCP server covers the everyday reads and writes.