Skip to content
UpVoiced Docs

API reference

Issue links and GitHub sync

GitHub, Linear and Jira issue links on posts, the GitHub status they sync in, suggested status changes, and the GitHub webhook settings.

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.

GitHub, Linear and Jira issue links of a post with synced GitHub status and any status suggestion (any member)

Authentication
API key or Dashboard session; API key scope read
Operation id
listPostLinks
Path parameters
NameTypeRequired
idstring (uuid)Yes
Headers
NameTypeRequired
x-workspacestring (uuid)Yes
Response 200: 17 fields
Response 200 (application/json)
NameTypeRequired
itemsarray of objectYes
items[].idstring (uuid)Yes
items[].post_idstring (uuid)Yes
items[].provider"github" | "linear" | "jira"Yes
items[].kind"issue" | "pull_request"Yes
items[].urlstringYes
items[].refstringYes
items[].status"open" | "closed" | "merged" | nullYes
items[].status_synced_atstring (date-time) | nullYes
items[].suggestionobject | nullYes
items[].suggestion.status_idstring (uuid)Yes
items[].suggestion.status_namestringYes
items[].suggestion.reason"completed" | "not_planned" | "merged" | "reopened"Yes
items[].suggestion.atstring (date-time)Yes
items[].created_atstring (date-time)Yes
items[].created_bystring (uuid)Yes
next_cursornullYes

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/links' \
  -H "Authorization: Bearer $UPVOICED_API_KEY" \
  -H "X-Workspace: $UPVOICED_WORKSPACE_ID"
TypeScript SDK
const data = await upvoiced.get('/v1/posts/{id}/links', { path: { id: '0190f5e2-4c1d-7a3b-8c2d-5e6f7a8b9c0d' } });
MCP

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

Link a GitHub issue or pull request, Linear issue or Jira issue by URL; the provider is detected from the URL only (at most 20 per post)

Authentication
API key or Dashboard session; API key scope write
Operation id
createPostLink
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
urlstringlength 1–2048Yes
Response 201: 15 fields
Response 201 (application/json)
NameTypeRequired
idstring (uuid)Yes
post_idstring (uuid)Yes
provider"github" | "linear" | "jira"Yes
kind"issue" | "pull_request"Yes
urlstringYes
refstringYes
status"open" | "closed" | "merged" | nullYes
status_synced_atstring (date-time) | nullYes
suggestionobject | nullYes
suggestion.status_idstring (uuid)Yes
suggestion.status_namestringYes
suggestion.reason"completed" | "not_planned" | "merged" | "reopened"Yes
suggestion.atstring (date-time)Yes
created_atstring (date-time)Yes
created_bystring (uuid)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/links' \
  -H "Authorization: Bearer $UPVOICED_API_KEY" \
  -H "X-Workspace: $UPVOICED_WORKSPACE_ID" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "url": "https://example.com/upvoiced"
}'
TypeScript SDK
const data = await upvoiced.post('/v1/posts/{id}/links', {
  path: { id: '0190f5e2-4c1d-7a3b-8c2d-5e6f7a8b9c0d' },
  body: { url: 'https://example.com/upvoiced' },
});
MCP

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

Remove an issue link from its post

Authentication
API key or Dashboard session; API key scope write
Operation id
deletePostLink
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/post-links/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/post-links/{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/post-links/{id}/suggestion/apply

Apply the status change a synced GitHub event suggested, through the normal post status update; clears the suggestion

Authentication
API key or Dashboard session; API key scope write
Operation id
applyPostLinkSuggestion
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
Response 200: 15 fields
Response 200 (application/json)
NameTypeRequired
idstring (uuid)Yes
post_idstring (uuid)Yes
provider"github" | "linear" | "jira"Yes
kind"issue" | "pull_request"Yes
urlstringYes
refstringYes
status"open" | "closed" | "merged" | nullYes
status_synced_atstring (date-time) | nullYes
suggestionobject | nullYes
suggestion.status_idstring (uuid)Yes
suggestion.status_namestringYes
suggestion.reason"completed" | "not_planned" | "merged" | "reopened"Yes
suggestion.atstring (date-time)Yes
created_atstring (date-time)Yes
created_bystring (uuid)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/post-links/0190f5e2-4c1d-7a3b-8c2d-5e6f7a8b9c0d/suggestion/apply' \
  -H "Authorization: Bearer $UPVOICED_API_KEY" \
  -H "X-Workspace: $UPVOICED_WORKSPACE_ID" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{}'
TypeScript SDK
const data = await upvoiced.post('/v1/post-links/{id}/suggestion/apply', {
  path: { id: '0190f5e2-4c1d-7a3b-8c2d-5e6f7a8b9c0d' },
  body: {},
});
MCP

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

POST/v1/post-links/{id}/suggestion/dismiss

Dismiss the status suggestion of an issue link (idempotent)

Authentication
API key or Dashboard session; API key scope write
Operation id
dismissPostLinkSuggestion
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
Response 200: 15 fields
Response 200 (application/json)
NameTypeRequired
idstring (uuid)Yes
post_idstring (uuid)Yes
provider"github" | "linear" | "jira"Yes
kind"issue" | "pull_request"Yes
urlstringYes
refstringYes
status"open" | "closed" | "merged" | nullYes
status_synced_atstring (date-time) | nullYes
suggestionobject | nullYes
suggestion.status_idstring (uuid)Yes
suggestion.status_namestringYes
suggestion.reason"completed" | "not_planned" | "merged" | "reopened"Yes
suggestion.atstring (date-time)Yes
created_atstring (date-time)Yes
created_bystring (uuid)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/post-links/0190f5e2-4c1d-7a3b-8c2d-5e6f7a8b9c0d/suggestion/dismiss' \
  -H "Authorization: Bearer $UPVOICED_API_KEY" \
  -H "X-Workspace: $UPVOICED_WORKSPACE_ID" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{}'
TypeScript SDK
const data = await upvoiced.post('/v1/post-links/{id}/suggestion/dismiss', {
  path: { id: '0190f5e2-4c1d-7a3b-8c2d-5e6f7a8b9c0d' },
  body: {},
});
MCP

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

GET/v1/github-sync

GitHub status sync settings: whether the receiver is on, its webhook path, events, masked secret and last deliveries (any member)

Authentication
API key or Dashboard session; API key scope read
Operation id
getGitHubSync
Headers
NameTypeRequired
x-workspacestring (uuid)Yes
Response 200: 8 fields
Response 200 (application/json)
NameTypeRequired
enabledbooleanYes
webhook_pathstringpattern ^\/webhooks\/github\/[0-9a-f-]{36}$Yes
eventsarray of "issues" | "pull_request"Yes
content_type"application/json"Yes
secret_hintstring | nullYes
created_atstring (date-time) | nullYes
last_delivery_atstring (date-time) | nullYes
last_ping_atstring (date-time) | 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/github-sync' \
  -H "Authorization: Bearer $UPVOICED_API_KEY" \
  -H "X-Workspace: $UPVOICED_WORKSPACE_ID"
TypeScript SDK
const data = await upvoiced.get('/v1/github-sync');
MCP

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

POST/v1/github-sync

Turn GitHub status sync on, or replace its webhook secret at once; the secret is shown in this response only (owner/admin)

Authentication
API key or Dashboard session; API key scope admin
Operation id
enableGitHubSync
Idempotency
Send an Idempotency-Key to make retries safe.
Headers
NameTypeRequired
x-workspacestring (uuid)Yes
idempotency-keystringpattern ^[A-Za-z0-9_.:-]{8,128}$No
Response 200: 9 fields
Response 200 (application/json)
NameTypeRequired
enabledbooleanYes
webhook_pathstringpattern ^\/webhooks\/github\/[0-9a-f-]{36}$Yes
eventsarray of "issues" | "pull_request"Yes
content_type"application/json"Yes
secret_hintstring | nullYes
created_atstring (date-time) | nullYes
last_delivery_atstring (date-time) | nullYes
last_ping_atstring (date-time) | nullYes
secretstring | nullpattern ^uvgh_[0-9A-Za-z]{43}$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/github-sync' \
  -H "Authorization: Bearer $UPVOICED_API_KEY" \
  -H "X-Workspace: $UPVOICED_WORKSPACE_ID" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{}'
TypeScript SDK
const data = await upvoiced.post('/v1/github-sync', { body: {} });
MCP

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

DELETE/v1/github-sync

Turn GitHub status sync off: the receiver answers 404 and its secret is deleted (owner/admin)

Authentication
API key or Dashboard session; API key scope admin
Operation id
disableGitHubSync
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/github-sync' \
  -H "Authorization: Bearer $UPVOICED_API_KEY" \
  -H "X-Workspace: $UPVOICED_WORKSPACE_ID"
TypeScript SDK
const data = await upvoiced.delete('/v1/github-sync');
MCP

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