Workspace
The workspace itself: settings, single sign-on, widget settings, deletion and restore.
Set up the SDK client used in the examples
Dashboard session only (API keys get 403 session_required):
import { UpVoiced } from '@upvoiced/sdk';
// Dashboard-session operations: the Clerk session token of a signed-in operator.
const upvoiced = new UpVoiced({
headers: { authorization: `Bearer ${sessionToken}` },
workspace: workspaceId,
});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/workspaces
List the caller's active workspaces
Response 200: 8 fields
| Name | Type | Required |
|---|---|---|
items | array of object | Yes |
items[].id | string (uuid) | Yes |
items[].name | stringlength 1–100 | Yes |
items[].slug | stringlength 3–32pattern ^[a-z0-9][a-z0-9-]*[a-z0-9]$ | Yes |
items[].portal_locale | "en" | "pt-BR" | "es" | "de" | "fr" | Yes |
items[].created_at | string (date-time) | Yes |
items[].updated_at | string (date-time) | Yes |
next_cursor | 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/workspaces' \
-H "Authorization: Bearer $UPVOICED_SESSION_TOKEN"const data = await upvoiced.get('/v1/workspaces');No MCP tool for this operation. The MCP server covers the everyday reads and writes.
POST/v1/workspaces
Create a workspace owned by the caller
| Name | Type | Required |
|---|---|---|
idempotency-key | stringpattern ^[A-Za-z0-9_.:-]{8,128}$ | No |
| Name | Type | Required |
|---|---|---|
name | stringlength 1–100 | Yes |
slug | stringlength 3–32pattern ^[a-z0-9][a-z0-9-]*[a-z0-9]$ | Yes |
portal_locale | "en" | "pt-BR" | "es" | "de" | "fr"default "en" | No |
accent | stringpattern ^#[0-9a-fA-F]{6}$ | No |
attribution | object | No |
attribution.utm_source | string | nulllength ≤ 100pattern ^[\w.-]+$ | Yes |
attribution.utm_medium | string | nulllength ≤ 100pattern ^[\w.-]+$ | Yes |
attribution.utm_campaign | string | nulllength ≤ 100pattern ^[\w.-]+$ | Yes |
attribution.utm_term | string | nulllength ≤ 100pattern ^[\w.-]+$ | No |
attribution.utm_content | string | nulllength ≤ 100pattern ^[\w.-]+$ | No |
attribution.referrer_domain | string | nulllength ≤ 253pattern ^[a-z0-9.-]*$ | Yes |
attribution.landing_path | string | nulllength ≤ 512pattern ^\/[^?#\s]*$ | Yes |
Response 201: 6 fields
| Name | Type | Required |
|---|---|---|
id | string (uuid) | Yes |
name | stringlength 1–100 | Yes |
slug | stringlength 3–32pattern ^[a-z0-9][a-z0-9-]*[a-z0-9]$ | Yes |
portal_locale | "en" | "pt-BR" | "es" | "de" | "fr" | 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/workspaces' \
-H "Authorization: Bearer $UPVOICED_SESSION_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"name": "Example",
"slug": "dark-mode"
}'const data = await upvoiced.post('/v1/workspaces', { body: { name: 'Example', slug: 'dark-mode' } });No MCP tool for this operation. The MCP server covers the everyday reads and writes.
GET/v1/workspace
Get the selected workspace
| Name | Type | Required |
|---|---|---|
x-workspace | string (uuid) | Yes |
Response 200: 6 fields
| Name | Type | Required |
|---|---|---|
id | string (uuid) | Yes |
name | stringlength 1–100 | Yes |
slug | stringlength 3–32pattern ^[a-z0-9][a-z0-9-]*[a-z0-9]$ | Yes |
portal_locale | "en" | "pt-BR" | "es" | "de" | "fr" | 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 'https://api.upvoiced.com/v1/workspace' \
-H "Authorization: Bearer $UPVOICED_API_KEY" \
-H "X-Workspace: $UPVOICED_WORKSPACE_ID"const data = await upvoiced.get('/v1/workspace');{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_workspaces",
"arguments": {}
}
}Tool list_workspaces.
PATCH/v1/workspace
Update workspace settings (owner/admin)
| Name | Type | Required |
|---|---|---|
x-workspace | string (uuid) | Yes |
| Name | Type | Required |
|---|---|---|
name | stringlength 1–100 | No |
slug | stringlength 3–32pattern ^[a-z0-9][a-z0-9-]*[a-z0-9]$ | No |
portal_locale | "en" | "pt-BR" | "es" | "de" | "fr" | No |
Response 200: 6 fields
| Name | Type | Required |
|---|---|---|
id | string (uuid) | Yes |
name | stringlength 1–100 | Yes |
slug | stringlength 3–32pattern ^[a-z0-9][a-z0-9-]*[a-z0-9]$ | Yes |
portal_locale | "en" | "pt-BR" | "es" | "de" | "fr" | 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 PATCH 'https://api.upvoiced.com/v1/workspace' \
-H "Authorization: Bearer $UPVOICED_API_KEY" \
-H "X-Workspace: $UPVOICED_WORKSPACE_ID" \
-H "Content-Type: application/json" \
-d '{
"name": "Example"
}'const data = await upvoiced.patch('/v1/workspace', { body: { name: 'Example' } });No MCP tool for this operation. The MCP server covers the everyday reads and writes.
POST/v1/workspace/switch
Verify membership and return the workspace and role to switch to
| Name | Type | Required |
|---|---|---|
x-workspace | string (uuid) | Yes |
idempotency-key | stringpattern ^[A-Za-z0-9_.:-]{8,128}$ | No |
Response 200: 9 fields
| Name | Type | Required |
|---|---|---|
workspace | object | Yes |
workspace.id | string (uuid) | Yes |
workspace.name | stringlength 1–100 | Yes |
workspace.slug | stringlength 3–32pattern ^[a-z0-9][a-z0-9-]*[a-z0-9]$ | Yes |
workspace.portal_locale | "en" | "pt-BR" | "es" | "de" | "fr" | Yes |
workspace.created_at | string (date-time) | Yes |
workspace.updated_at | string (date-time) | Yes |
role | "owner" | "admin" | "member" | Yes |
operator_id | string (uuid) | No |
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/workspace/switch' \
-H "Authorization: Bearer $UPVOICED_SESSION_TOKEN" \
-H "X-Workspace: $UPVOICED_WORKSPACE_ID" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{}'const data = await upvoiced.post('/v1/workspace/switch', { body: {} });No MCP tool for this operation. The MCP server covers the everyday reads and writes.
GET/v1/workspace/sso
End-user SSO state: enabled, audience, secret dates; never the secret (owner/admin)
| Name | Type | Required |
|---|---|---|
x-workspace | string (uuid) | Yes |
Response 200: 5 fields
| Name | Type | Required |
|---|---|---|
enabled | boolean | Yes |
configured | boolean | Yes |
audience | string (uuid) | Yes |
secret_created_at | string (date-time) | null | Yes |
previous_secret_expires_at | string (date-time) | 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/workspace/sso' \
-H "Authorization: Bearer $UPVOICED_API_KEY" \
-H "X-Workspace: $UPVOICED_WORKSPACE_ID"const data = await upvoiced.get('/v1/workspace/sso');No MCP tool for this operation. The MCP server covers the everyday reads and writes.
PATCH/v1/workspace/sso
Accept or stop accepting SSO tokens; needs a secret to enable (owner/admin)
| Name | Type | Required |
|---|---|---|
x-workspace | string (uuid) | Yes |
| Name | Type | Required |
|---|---|---|
enabled | boolean | Yes |
Response 200: 5 fields
| Name | Type | Required |
|---|---|---|
enabled | boolean | Yes |
configured | boolean | Yes |
audience | string (uuid) | Yes |
secret_created_at | string (date-time) | null | Yes |
previous_secret_expires_at | string (date-time) | null | Yes |
Errors: 400, 401, 403, 404, 409, 413, 422, 429, 500, 503, all in the standard error shape.
curl -X PATCH 'https://api.upvoiced.com/v1/workspace/sso' \
-H "Authorization: Bearer $UPVOICED_API_KEY" \
-H "X-Workspace: $UPVOICED_WORKSPACE_ID" \
-H "Content-Type: application/json" \
-d '{
"enabled": true
}'const data = await upvoiced.patch('/v1/workspace/sso', { body: { enabled: true } });No MCP tool for this operation. The MCP server covers the everyday reads and writes.
POST/v1/workspace/sso/rotate
Create or rotate the SSO secret, shown once; the old one verifies for grace_hours (owner/admin, re-auth ≤ 10 min)
| Name | Type | Required |
|---|---|---|
x-workspace | string (uuid) | Yes |
idempotency-key | stringpattern ^[A-Za-z0-9_.:-]{8,128}$ | No |
| Name | Type | Required |
|---|---|---|
grace_hours | integervalue 0–168default 24 | No |
Response 200: 6 fields
| Name | Type | Required |
|---|---|---|
enabled | boolean | Yes |
configured | boolean | Yes |
audience | string (uuid) | Yes |
secret_created_at | string (date-time) | null | Yes |
previous_secret_expires_at | string (date-time) | null | Yes |
secret | stringpattern ^uvsso_[A-Za-z0-9_-]{43}$ | 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/workspace/sso/rotate' \
-H "Authorization: Bearer $UPVOICED_SESSION_TOKEN" \
-H "X-Workspace: $UPVOICED_WORKSPACE_ID" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"grace_hours": 24
}'const data = await upvoiced.post('/v1/workspace/sso/rotate', { body: { grace_hours: 24 } });No MCP tool for this operation. The MCP server covers the everyday reads and writes.
GET/v1/workspace/widget
Widget settings: allowed origins, the always-allowed portal origin, enabled tabs, install date (any member)
| Name | Type | Required |
|---|---|---|
x-workspace | string (uuid) | Yes |
Response 200: 4 fields
| Name | Type | Required |
|---|---|---|
allowed_origins | array of stringitems ≤ 50 | Yes |
first_party_origins | array of stringitems ≤ 4 | Yes |
tabs | array of "feedback" | "roadmap" | "whats-new"items 1–3 | Yes |
installed_at | string (date-time) | 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/workspace/widget' \
-H "Authorization: Bearer $UPVOICED_API_KEY" \
-H "X-Workspace: $UPVOICED_WORKSPACE_ID"const data = await upvoiced.get('/v1/workspace/widget');No MCP tool for this operation. The MCP server covers the everyday reads and writes.
PATCH/v1/workspace/widget
Set the exact browser origins allowed on the end-user API and the enabled widget tabs (owner/admin)
| Name | Type | Required |
|---|---|---|
x-workspace | string (uuid) | Yes |
| Name | Type | Required |
|---|---|---|
allowed_origins | array of stringitems ≤ 50 | No |
tabs | array of "feedback" | "roadmap" | "whats-new"items 1–3 | No |
Response 200: 4 fields
| Name | Type | Required |
|---|---|---|
allowed_origins | array of stringitems ≤ 50 | Yes |
first_party_origins | array of stringitems ≤ 4 | Yes |
tabs | array of "feedback" | "roadmap" | "whats-new"items 1–3 | Yes |
installed_at | string (date-time) | null | Yes |
Errors: 400, 401, 403, 404, 409, 413, 422, 429, 500, 503, all in the standard error shape.
curl -X PATCH 'https://api.upvoiced.com/v1/workspace/widget' \
-H "Authorization: Bearer $UPVOICED_API_KEY" \
-H "X-Workspace: $UPVOICED_WORKSPACE_ID" \
-H "Content-Type: application/json" \
-d '{
"allowed_origins": [
"Example allowed origins"
]
}'const data = await upvoiced.patch('/v1/workspace/widget', { body: { allowed_origins: ['Example allowed origins'] } });No MCP tool for this operation. The MCP server covers the everyday reads and writes.
GET/v1/workspace/deletion
Deletion state, purge date and whether a restore is possible (owner/admin)
| Name | Type | Required |
|---|---|---|
x-workspace | string (uuid) | Yes |
Response 200: 4 fields
| Name | Type | Required |
|---|---|---|
state | "active" | "scheduled" | "purging" | Yes |
deleted_at | string (date-time) | null | Yes |
purge_after | string (date-time) | null | Yes |
restorable | boolean | Yes |
Errors: 400, 401, 403, 404, 409, 413, 422, 429, 500, 503, all in the standard error shape.
curl 'https://api.upvoiced.com/v1/workspace/deletion' \
-H "Authorization: Bearer $UPVOICED_API_KEY" \
-H "X-Workspace: $UPVOICED_WORKSPACE_ID"const data = await upvoiced.get('/v1/workspace/deletion');No MCP tool for this operation. The MCP server covers the everyday reads and writes.
POST/v1/workspace/deletion
Owner-only, re-authenticated soft deletion with typed slug
| Name | Type | Required |
|---|---|---|
x-workspace | string (uuid) | Yes |
idempotency-key | stringpattern ^[A-Za-z0-9_.:-]{8,128}$ | No |
| Name | Type | Required |
|---|---|---|
confirmation_slug | stringlength 3–32pattern ^[a-z0-9][a-z0-9-]*[a-z0-9]$ | Yes |
Response 202: 2 fields
| Name | Type | Required |
|---|---|---|
deleted_at | string (date-time) | Yes |
purge_after | 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/workspace/deletion' \
-H "Authorization: Bearer $UPVOICED_SESSION_TOKEN" \
-H "X-Workspace: $UPVOICED_WORKSPACE_ID" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"confirmation_slug": "acme"
}'const data = await upvoiced.post('/v1/workspace/deletion', { body: { confirmation_slug: 'acme' } });No MCP tool for this operation. The MCP server covers the everyday reads and writes.
POST/v1/workspace/restore
Restore a soft-deleted workspace within 30 days, before purge starts (owner)
| Name | Type | Required |
|---|---|---|
x-workspace | string (uuid) | Yes |
idempotency-key | stringpattern ^[A-Za-z0-9_.:-]{8,128}$ | No |
Response 200: 6 fields
| Name | Type | Required |
|---|---|---|
id | string (uuid) | Yes |
name | stringlength 1–100 | Yes |
slug | stringlength 3–32pattern ^[a-z0-9][a-z0-9-]*[a-z0-9]$ | Yes |
portal_locale | "en" | "pt-BR" | "es" | "de" | "fr" | 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/workspace/restore' \
-H "Authorization: Bearer $UPVOICED_API_KEY" \
-H "X-Workspace: $UPVOICED_WORKSPACE_ID" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{}'const data = await upvoiced.post('/v1/workspace/restore', { body: {} });No MCP tool for this operation. The MCP server covers the everyday reads and writes.