Skip to content
UpVoiced Docs

API reference

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)

Authentication
API key or Dashboard session; API key scope read
Operation id
listNotes
Path parameters
NameTypeRequired
idstring (uuid)Yes
Headers
NameTypeRequired
x-workspacestring (uuid)Yes
Response 200: 13 fields
Response 200 (application/json)
NameTypeRequired
itemsarray of objectYes
items[].idstring (uuid)Yes
items[].post_idstring (uuid)Yes
items[].operator_idstring (uuid)Yes
items[].body_mdstringYes
items[].mention_idsarray of string (uuid)Yes
items[].reactionsarray of objectYes
items[].reactions[].emojistringYes
items[].reactions[].countintegervalue ≥ 0Yes
items[].reactions[].operator_idsarray of string (uuid)Yes
items[].created_atstring (date-time)Yes
items[].updated_atstring (date-time)Yes
next_cursorstring | nullYes

Errors: 400, 401, 403, 404, 409, 413, 422, 429, 500, 503, all in the standard error shape.

curl
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"
TypeScript SDK
const data = await upvoiced.get('/v1/posts/{id}/notes', { path: { id: '0190f5e2-4c1d-7a3b-8c2d-5e6f7a8b9c0d' } });
MCP

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

Authentication
API key or Dashboard session; API key scope write
Operation id
createNote
Idempotency
Send an Idempotency-Key to make retries safe.
Path parameters
NameTypeRequired
idstring (uuid)Yes
Headers
NameTypeRequired
x-workspacestring (uuid)Yes
idempotency-keystringpattern ^[A-Za-z0-9_.:-]{8,128}$No
Request body (JSON)
NameTypeRequired
body_mdstringlength ≤ 10000Yes
mention_idsarray of string (uuid)items ≤ 20default []No
Response 201: 11 fields
Response 201 (application/json)
NameTypeRequired
idstring (uuid)Yes
post_idstring (uuid)Yes
operator_idstring (uuid)Yes
body_mdstringYes
mention_idsarray of string (uuid)Yes
reactionsarray of objectYes
reactions[].emojistringYes
reactions[].countintegervalue ≥ 0Yes
reactions[].operator_idsarray of string (uuid)Yes
created_atstring (date-time)Yes
updated_atstring (date-time)Yes

Errors: 400, 401, 403, 404, 409, 413, 422, 429, 500, 503, all in the standard error shape.

curl
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."
}'
TypeScript SDK
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.' },
});
MCP
{
  "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)

Authentication
API key or Dashboard session; API key scope write
Operation id
deleteNote
Path parameters
NameTypeRequired
idstring (uuid)Yes
Headers
NameTypeRequired
x-workspacestring (uuid)Yes
Response 200: 1 fields
Response 200 (application/json)
NameTypeRequired
oktrueYes

Errors: 400, 401, 403, 404, 409, 413, 422, 429, 500, 503, all in the standard error shape.

curl
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"
TypeScript SDK
const data = await upvoiced.delete('/v1/notes/{id}', { path: { id: '0190f5e2-4c1d-7a3b-8c2d-5e6f7a8b9c0d' } });
MCP

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)

Authentication
API key or Dashboard session; API key scope write
Operation id
addNoteReaction
Idempotency
Send an Idempotency-Key to make retries safe.
Path parameters
NameTypeRequired
idstring (uuid)Yes
Headers
NameTypeRequired
x-workspacestring (uuid)Yes
idempotency-keystringpattern ^[A-Za-z0-9_.:-]{8,128}$No
Request body (JSON)
NameTypeRequired
emojistringlength 1–32Yes
Response 200: 11 fields
Response 200 (application/json)
NameTypeRequired
idstring (uuid)Yes
post_idstring (uuid)Yes
operator_idstring (uuid)Yes
body_mdstringYes
mention_idsarray of string (uuid)Yes
reactionsarray of objectYes
reactions[].emojistringYes
reactions[].countintegervalue ≥ 0Yes
reactions[].operator_idsarray of string (uuid)Yes
created_atstring (date-time)Yes
updated_atstring (date-time)Yes

Errors: 400, 401, 403, 404, 409, 413, 422, 429, 500, 503, all in the standard error shape.

curl
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": "👍"
}'
TypeScript SDK
const data = await upvoiced.post('/v1/notes/{id}/reactions', {
  path: { id: '0190f5e2-4c1d-7a3b-8c2d-5e6f7a8b9c0d' },
  body: { emoji: '👍' },
});
MCP

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)

Authentication
API key or Dashboard session; API key scope write
Operation id
removeNoteReaction
Path parameters
NameTypeRequired
idstring (uuid)Yes
Headers
NameTypeRequired
x-workspacestring (uuid)Yes
Request body (JSON)
NameTypeRequired
emojistringlength 1–32Yes
Response 200: 11 fields
Response 200 (application/json)
NameTypeRequired
idstring (uuid)Yes
post_idstring (uuid)Yes
operator_idstring (uuid)Yes
body_mdstringYes
mention_idsarray of string (uuid)Yes
reactionsarray of objectYes
reactions[].emojistringYes
reactions[].countintegervalue ≥ 0Yes
reactions[].operator_idsarray of string (uuid)Yes
created_atstring (date-time)Yes
updated_atstring (date-time)Yes

Errors: 400, 401, 403, 404, 409, 413, 422, 429, 500, 503, all in the standard error shape.

curl
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": "👍"
}'
TypeScript SDK
const data = await upvoiced.delete('/v1/notes/{id}/reactions', {
  path: { id: '0190f5e2-4c1d-7a3b-8c2d-5e6f7a8b9c0d' },
  body: { emoji: '👍' },
});
MCP

No MCP tool for this operation. The MCP server covers the everyday reads and writes.