REST API

Base URL: https://api.srvo.app/api/v1. Self-host: use your server origin with /api/v1.

Authentication: Authorization: Bearer <API key>. See API keys. OAuth connections use the MCP resource and are refused on REST; see Connect AI apps. Session requests use the same policy.

Pagination: cursor and limit, default 50, maximum 200. Follow nextCursor until null. Per-operation schemas below define which lists support pagination.

Idempotency and confirmation headers appear on the operations that accept them. Rate-limited errors include Retry-After when available. Budgets depend on runtime configuration; there is no fixed universal request rate.

Errors: { error: { code: “VALIDATION” / “TIMEOUT” / “UNAUTHENTICATED” / “FORBIDDEN” / “NOT_FOUND” / “CONFLICT” / “STALE_PREVIEW” / “RATE_LIMITED” / “MODULE_DISABLED” / “QUOTA_EXCEEDED” / “AI_NOT_CONFIGURED” / “VOICE_BUSY” / “VOICE_CAP” / “VOICE_OFF” / “NOT_AVAILABLE” / “ATTACHMENT_TYPE” / “ATTACHMENT_TOO_LARGE” / “ATTACHMENT_LIMIT” / “ATTACHMENT_NOT_READY” / “ATTACHMENT_UNREADABLE” / “ATTACHMENT_PARSE_DISABLED” / “INTERNAL”, key: string, params?: object, current?: object, fieldErrors?: object, retryAfter?: integer } }.

  • 400: Validation error
  • 401: Not signed in
  • 403: Forbidden or module disabled
  • 404: Not found (also for records you can’t see)
  • 409: Conflict or stale preview
  • 429: Rate limited

ai

GET /ai/credits

Read workspace Sergio credits

Capability: ai.credits.read. Kind: read.

No input fields.

Output: { plan: string, planCredits: integer, used: integer, held: integer, mode: “payg” / “hard”, notice: “none” / “low” / “overPlan” / “capNear” / “exhausted”, nextReset: string, spendCapCents?: integer, extraCents?: integer, upgrade?: { plan: string, savingCents: integer } }.

POST /ai/credits

Set Sergio credit mode and monthly spending cap

Capability: ai.credits.manage. Kind: write.

Field In Type Required
mode body “payg” / “hard” yes
spendCapEuros body integer yes

Output: { plan: string, planCredits: integer, used: integer, held: integer, mode: “payg” / “hard”, notice: “none” / “low” / “overPlan” / “capNear” / “exhausted”, nextReset: string, spendCapCents?: integer, extraCents?: integer, upgrade?: { plan: string, savingCents: integer } }.

GET /ai/credits/usage

Read your chat message credits and your UTC daily and monthly totals. Current streaming answer is not settled yet.

Capability: ai.credits.read. Kind: read.

Field In Type Required
conversationId query string yes

Output: { messages: array, today: number, month: number }.

boards

POST /metrics/present

Compute a widget query and return totals, up to 20 groups and a widget block. Pass widget and optional timeZone; no paging.

Capability: boards.records.read. Kind: read.

Field In Type Required
timeZone body string no
widget body { family?: “metric”, id?: string, kind: “kpi” / “progress” / “bar” / “line” / “stacked” / “table” / “donut”, title?: string, tableId: string, metrics: array, groupField?: string, dateField?: string, bucket?: “day” / “week” / “month”, range: “all” / “thisWeek” / “lastWeek” / “thisMonth” / “lastMonth” / “last7” / “last30” / “last90” / “last365”, compare?: boolean, size?: { w: integer, h: integer }, segmentField?: string, stackMode?: “stacked” / “grouped”, area?: boolean, topN?: integer, target?: number, targetMode?: “goal” / “limit”, filters?: array } yes

Output: { status: “complete” / “partial” / “stale” / “restricted”, totals: array, groups: array, block: { blockId: string, protocol: “widget@1”, widget: object } or null }.

POST /metrics/query

Compute sums, averages, counts and percents over a table’s readable rows, optionally grouped by a select/status field or date bucket.

Capability: boards.records.read. Kind: read.

Field In Type Required
dateField body string no
filters body array<{ field: string, op: “eq” / “neq”, value: string or number or boolean } or { field: string, op: “in”, values: array } or { field: string, op: “gt” / “gte” / “lt” / “lte”, value: number or string } or { field: string, op: “isEmpty” / “isNotEmpty” }> no
groupBy body array<{ field: string } or { date: “day” / “week” / “month” }> no
metrics body array<{ op: “sum” / “avg” / “min” / “max” / “countRows” / “countNonNull” / “countDistinct” / “percent”, field?: string, of?: “countRows” / “sum”, numerator?: array, label?: string }> yes
range body { preset: “today” / “thisWeek” / “lastWeek” / “thisMonth” / “lastMonth” } or { lastDays: integer } or { from: string, to: string } no
tableId body string yes
timeZone body string no

Output: { status: “complete” / “partial” / “stale” / “restricted”, metrics: array, totals: array, groups: array, range: { startInclusive: string, endExclusive: string } or null, computedAt: string, warnings: array<“restricted” / “groupLimit”> }.

POST /metrics/validate

Check a metric query against the table’s fields and the caller’s field access, without running it.

Capability: boards.records.read. Kind: read.

Field In Type Required
dateField body string no
filters body array<{ field: string, op: “eq” / “neq”, value: string or number or boolean } or { field: string, op: “in”, values: array } or { field: string, op: “gt” / “gte” / “lt” / “lte”, value: number or string } or { field: string, op: “isEmpty” / “isNotEmpty” }> no
groupBy body array<{ field: string } or { date: “day” / “week” / “month” }> no
metrics body array<{ op: “sum” / “avg” / “min” / “max” / “countRows” / “countNonNull” / “countDistinct” / “percent”, field?: string, of?: “countRows” / “sum”, numerator?: array, label?: string }> yes
range body { preset: “today” / “thisWeek” / “lastWeek” / “thisMonth” / “lastMonth” } or { lastDays: integer } or { from: string, to: string } no
tableId body string yes
timeZone body string no

Output: { ok: boolean, restricted: boolean, issues: array }.

GET /records/{recordId}/activity

Return permission-masked record history. Pass recordId and optional cursor/limit; follow nextCursor for more.

Capability: boards.records.read. Kind: read.

Field In Type Required
recordId path string yes
cursor query string no
limit query integer no

Output: { items: array, nextCursor: string or null }.

POST /tables/{tableId}/records

Create a record in a table.

Capability: boards.records.create. Kind: write.

Field In Type Required
tableId path string yes
Idempotency-Key header string yes
fields body object yes
id body string no

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { record: { id: string, tableId: string, spaceId: string, version: integer, rank: string, createdBy: string or null, data: object, createdAt: string, updatedAt: string, restrictedFields?: array }, changeId: integer }.

GET /tables/{tableId}/export

Export tableId and optional viewId as masked CSV/XLSX. Returns filename, contentType and base64 body over MCP, up to 1 MiB; use REST for larger files. No paging.

Capability: boards.records.read. Kind: read.

Field In Type Required
tableId path string yes
viewId query string no
format query “csv” / “xlsx” no
locale query “en” / “hu” no

Output: string.

GET /records/{recordId}

Get one record by id.

Capability: boards.records.read. Kind: read.

Field In Type Required
recordId path string yes

Output: { record: { id: string, tableId: string, spaceId: string, version: integer, rank: string, createdBy: string or null, data: object, createdAt: string, updatedAt: string, restrictedFields?: array } }.

GET /tables/{tableId}/records

List the records of a table, ordered by id, one page at a time.

Capability: boards.records.read. Kind: read.

Field In Type Required
tableId path string yes
cursor query string no
limit query integer no

Output: { items: array, nextCursor: string or null }.

POST /records/{recordId}/move

Move a record between readable neighbours and/or patch its group fields in one versioned update.

Capability: boards.records.update. Kind: write.

Field In Type Required
recordId path string yes
Idempotency-Key header string yes
afterId body string or null no
baseVersion body integer yes
beforeId body string or null no
fields body object no

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { record: { id: string, tableId: string, spaceId: string, version: integer, rank: string, createdBy: string or null, data: object, createdAt: string, updatedAt: string, restrictedFields?: array }, changeId: integer }.

POST /trash/purge

Permanently delete trashed records, or empty the trash (recordIds: “all”). Preview first, then commit.

Capability: boards.records.trash. Kind: destructive.

Field In Type Required
Srvo-Confirmation header string no
recordIds body “all” or array yes
spaceIds body array no

Srvo-Confirmation: Without it the call returns a preview and a token; send the token back to commit.

Output: { mode: “hidden” / “deleted”, count: integer, spaceCount?: integer } or { preview: { summary: string, counts: object, warnings: array }, confirmationToken: string, expiresAt: string }.

POST /records/{recordId}/restore

Restore a trashed record at its current version. No preview required.

Capability: boards.records.trash. Kind: write.

Field In Type Required
recordId path string yes
Idempotency-Key header string yes
baseVersion body integer yes

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { record: { id: string, tableId: string, spaceId: string, version: integer, rank: string, createdBy: string or null, data: object, createdAt: string, updatedAt: string, restrictedFields?: array }, changeId: integer }.

POST /records/titles

Resolve up to 500 recordIds to visible id/title pairs; unreadable records are omitted. No paging.

Capability: boards.records.read. Kind: read.

Field In Type Required
recordIds body array yes

Output: { items: array }.

POST /records/{recordId}/trash

Move a record to the trash (restorable for 30 days in the cloud). Preview first, then commit.

Capability: boards.records.trash. Kind: destructive.

Field In Type Required
recordId path string yes
Srvo-Confirmation header string no

Srvo-Confirmation: Without it the call returns a preview and a token; send the token back to commit.

Output: { recordId: string, trashedAt: string, changeId: integer } or { preview: { summary: string, counts: object, warnings: array }, confirmationToken: string, expiresAt: string }.

PATCH /records/{recordId}

Update some fields of a record. Fields not sent stay as they are.

Capability: boards.records.update. Kind: write.

Field In Type Required
recordId path string yes
Idempotency-Key header string yes
baseVersion body integer no
fields body object yes

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { record: { id: string, tableId: string, spaceId: string, version: integer, rank: string, createdBy: string or null, data: object, createdAt: string, updatedAt: string, restrictedFields?: array }, changeId: integer }.

core

POST /api-keys

Create an API key. The secret is returned once.

Capability: core.self.read. Kind: write.

Field In Type Required
kind body “personal” / “workspace” yes
name body string yes
scope body { mode: “read” / “read-write”, spaces?: array, capabilities?: array, actions?: array } yes
ttlDays body 30 or 90 or 365 or null yes

Output: { key: { id: string, ownerMemberId: string, kind: “personal” / “workspace”, name: string, prefix: string, scope: object, expiresAt: string or null, lastUsedAt: string or null, revokedAt: string or null, createdAt: string, createdBy: string, createdByName?: string }, secret: string }.

GET /api-keys

List API key metadata.

Capability: core.self.read. Kind: read.

Field In Type Required
kind query “personal” / “workspace” no

Output: { items: array }.

POST /api-keys/{keyId}/revoke

Preview and revoke an API key.

Capability: core.self.read. Kind: destructive.

Field In Type Required
keyId path string yes
Srvo-Confirmation header string no

Srvo-Confirmation: Without it the call returns a preview and a token; send the token back to commit.

Output: { id: string, ownerMemberId: string, kind: “personal” / “workspace”, name: string, prefix: string, scope: { mode: “read” / “read-write”, spaces?: array, capabilities?: array, actions?: array }, expiresAt: string or null, lastUsedAt: string or null, revokedAt: string or null, createdAt: string, createdBy: string, createdByName?: string } or { preview: { summary: string, counts: object, warnings: array }, confirmationToken: string, expiresAt: string }.

GET /me/email-preferences

Read my email notification setting (off, batched every 15 minutes, or daily).

Capability: core.self.read. Kind: read.

No input fields.

Output: { notifications: “off” / “batched” / “daily” }.

PUT /me/email-preferences

Change my email notification setting.

Capability: core.self.read. Kind: write.

Field In Type Required
notifications body “off” / “batched” / “daily” yes

Output: { notifications: “off” / “batched” / “daily” }.

POST /grants

Grant a member or team a capability at tenant, space or exact item scope.

Capability: core.grants.manage. Kind: write.

Field In Type Required
Idempotency-Key header string no
capability body string yes
effect body “allow” / “deny” no
id body string no
scope body { kind: “tenant” } or { kind: “space”, id: string } or { kind: “item”, id: string } yes
subject body { kind: “member”, id: string } or { kind: “team”, id: string } yes

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { grant: { subject: object, scope: object, capability: string, effect: “allow” / “deny”, id: string, version: integer }, changeId: integer }.

GET /grants

List explicit capability grants in this tenant (owners and admins).

Capability: core.grants.manage. Kind: read.

No input fields.

Output: { items: array }.

POST /grants/{grantId}/revoke

Revoke an explicit grant and require sync clients to re-authorize.

Capability: core.grants.manage. Kind: write.

Field In Type Required
grantId path string yes
Idempotency-Key header string no
baseVersion body integer yes

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { grant: { subject: object, scope: object, capability: string, effect: “allow” / “deny”, id: string, version: integer }, changeId: integer }.

GET /home/tasks

My readable assigned tasks across tables, filtered and paged in SQL.

Capability: core.self.read. Kind: read.

Field In Type Required
cursor query string no
limit query integer no
bucket query “all” / “today” / “overdue” / “upcoming” / “no_date” / “done_today” no
timeZone query string no

Output: { items: array, nextCursor: string or null }.

POST /invites/{inviteId}/cancel

Cancel an open invite (its link stops working).

Capability: core.invites.manage. Kind: write.

Field In Type Required
inviteId path string yes
Idempotency-Key header string no

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { invite: { id: string, email: string, role: “owner” / “admin” / “member” / “limited” / “guest”, teamIds: array, locale: “en” / “hu”, status: “pending” / “expired” / “accepted” / “revoked”, invitedBy: string, createdAt: string, sentAt: string, expiresAt: string } }.

POST /invites

Invite someone by email. The UI returns the link once; MCP never returns invite tokens. Emails it when a provider is set.

Capability: core.invites.manage. Kind: write.

Field In Type Required
Idempotency-Key header string no
email body string yes
locale body “en” / “hu” no
role body “owner” / “admin” / “member” / “limited” / “guest” no
teamIds body array no
ttlDays body integer no

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { invite: { id: string, email: string, role: “owner” / “admin” / “member” / “limited” / “guest”, teamIds: array, locale: “en” / “hu”, status: “pending” / “expired” / “accepted” / “revoked”, invitedBy: string, createdAt: string, sentAt: string, expiresAt: string }, url: string or null, delivery: “email” / “link” }.

GET /invites

List invites (pending and expired by default).

Capability: core.invites.manage. Kind: read.

Field In Type Required
includeClosed query boolean no
cursor query string no
limit query integer no

Output: { items: array, nextCursor: string or null }.

POST /invites/{inviteId}/resend

Resend an open invite with a fresh link and expiry (the old link stops working).

Capability: core.invites.manage. Kind: write.

Field In Type Required
inviteId path string yes
Idempotency-Key header string no
ttlDays body integer no

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { invite: { id: string, email: string, role: “owner” / “admin” / “member” / “limited” / “guest”, teamIds: array, locale: “en” / “hu”, status: “pending” / “expired” / “accepted” / “revoked”, invitedBy: string, createdAt: string, sentAt: string, expiresAt: string }, url: string or null, delivery: “email” / “link” }.

POST /links

Link an editable source to a readable target.

Capability: core.links.write. Kind: write.

Field In Type Required
from body { module: string, kind: string, id: string } yes
id body string no
rank body string no
rel body string no
to body { module: string, kind: string, id: string } yes

Output: { link: { id: string, from: object, to: object, rel: string, rank: string, createdBy: string or null, createdAt: string, version: integer }, changeId: integer }.

POST /links/list

List outgoing links and backlinks visible now.

Capability: core.links.read. Kind: read.

Field In Type Required
cursor body string no
entity body { module: string, kind: string, id: string } yes
limit body integer no

Output: { items: array, nextCursor: string or null }.

DELETE /links/{linkId}

Remove a link, keeping both entities.

Capability: core.links.write. Kind: write.

Field In Type Required
linkId path string yes
baseVersion query integer yes

Output: { linkId: string, changeId: integer }.

PATCH /links/{linkId}/rank

Set a link’s ordering rank.

Capability: core.links.write. Kind: write.

Field In Type Required
linkId path string yes
baseVersion body integer no
rank body string yes

Output: { link: { id: string, from: object, to: object, rel: string, rank: string, createdBy: string or null, createdAt: string, version: integer }, changeId: integer }.

GET /me/capabilities

Read your effective tenant capabilities and per-space grants in this workspace.

Capability: core.self.read. Kind: read.

No input fields.

Output: { capabilities: array, spaces: array, items: array }.

GET /members

List the workspace’s members (people and agents) with role, status, teams and last activity.

Capability: core.members.read. Kind: read.

Field In Type Required
kind query “person” / “agent” no
status query “invited” / “active” / “suspended” / “removed” no
includeRemoved query boolean no
cursor query string no
limit query integer no

Output: { items: array, nextCursor: string or null }.

POST /members/{memberId}/reactivate

Reactivate a suspended member.

Capability: core.members.manage. Kind: write.

Field In Type Required
memberId path string yes
Idempotency-Key header string no

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { member: { id: string, kind: “person” / “agent”, name: string, email: string or null, role: string, status: “invited” / “active” / “suspended” / “removed”, teamIds: array, ownerMemberId: string or null, agentScopes: array or null, lastActiveAt: string or null, createdAt: string, version: integer }, changeId: integer }.

POST /members/{memberId}/remove

Remove a member (offboarding): hand their spaces, private items and views to another member, remove their agents and team memberships, end their access.

Capability: core.members.manage. Kind: destructive.

Field In Type Required
memberId path string yes
Idempotency-Key header string no
Srvo-Confirmation header string no
reassignTo body string no

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Srvo-Confirmation: Without it the call returns a preview and a token; send the token back to commit.

Output: { member: { id: string, kind: “person” / “agent”, name: string, email: string or null, role: string, status: “invited” / “active” / “suspended” / “removed”, teamIds: array, ownerMemberId: string or null, agentScopes: array or null, lastActiveAt: string or null, createdAt: string, version: integer }, counts: { spaces: integer, items: integer, views: integer, agents: integer, teams: integer }, reassignedTo: string or null, changeId: integer } or { preview: { summary: string, counts: object, warnings: array }, confirmationToken: string, expiresAt: string }.

POST /members/{memberId}/suspend

Suspend a member: their sessions, keys and agents stop working until reactivated.

Capability: core.members.manage. Kind: write.

Field In Type Required
memberId path string yes
Idempotency-Key header string no

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { member: { id: string, kind: “person” / “agent”, name: string, email: string or null, role: string, status: “invited” / “active” / “suspended” / “removed”, teamIds: array, ownerMemberId: string or null, agentScopes: array or null, lastActiveAt: string or null, createdAt: string, version: integer }, changeId: integer }.

POST /members/{memberId}/role

Change a member’s role (role ceiling applies; only owners make owners; one owner always stays).

Capability: core.members.manage. Kind: write.

Field In Type Required
memberId path string yes
Idempotency-Key header string no
role body “owner” / “admin” / “member” / “limited” / “guest” or string yes

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { member: { id: string, kind: “person” / “agent”, name: string, email: string or null, role: string, status: “invited” / “active” / “suspended” / “removed”, teamIds: array, ownerMemberId: string or null, agentScopes: array or null, lastActiveAt: string or null, createdAt: string, version: integer }, changeId: integer }.

PUT /modules

Enable or hide a workspace module without deleting its data.

Capability: core.modules.manage. Kind: write.

Field In Type Required
enabled body boolean yes
module body “boards” / “notes” / “track” / “files” / “flows” / “send” yes

Output: { module: “boards” / “notes” / “track” / “files” / “flows” / “send”, enabled: boolean }.

POST /notifications/archive

Update my currently readable notifications: archive.

Capability: core.self.read. Kind: write.

Field In Type Required
archived body boolean no
ids body array yes

Output: { changeIds: array }.

POST /notifications

Send a custom inbox notification to up to ten workspace members.

Capability: core.notifications.create. Kind: write.

Field In Type Required
Idempotency-Key header string yes
memberIds body array yes
message body string yes
target body { kind: “record” / “table” / “view” / “note”, id: string } yes

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { ok: true }.

GET /notifications

My persisted notifications, rechecked against current target visibility.

Capability: core.self.read. Kind: read.

Field In Type Required
cursor query string no
limit query integer no
state query “active” / “archived” / “all” no
unreadOnly query boolean no

Output: { items: array, nextCursor: string or null, unreadCount: integer }.

POST /notifications/read-all

Update my currently readable notifications: markAllRead.

Capability: core.self.read. Kind: write.

No input fields.

Output: { changeIds: array }.

POST /notifications/read

Update my currently readable notifications: markRead.

Capability: core.self.read. Kind: write.

Field In Type Required
ids body array yes
read body boolean no

Output: { changeIds: array }.

POST /notifications/snooze

Update my currently readable notifications: snooze.

Capability: core.self.read. Kind: write.

Field In Type Required
ids body array yes
until body string or null yes

Output: { changeIds: array }.

GET /notifications/unread-count

Count currently readable, active, unsnoozed unread notifications.

Capability: core.self.read. Kind: read.

No input fields.

Output: { unreadCount: integer }.

GET /core/recents

Visible personal recents for records, tables, views and notes, bounded to 50.

Capability: core.self.read. Kind: read.

Field In Type Required
limit query integer no

Output: { items: array }.

POST /core/recents

Remember a readable personal navigation target.

Capability: core.self.read. Kind: write.

Field In Type Required
id body string yes
kind body “record” / “table” / “view” / “note” yes

Output: { changeIds: array }.

POST /roles

Create a custom role with capability patterns and row/field restrictions.

Capability: core.roles.manage. Kind: write.

Field In Type Required
Idempotency-Key header string no
capabilities body array yes
fieldRules body array<{ tableId: string, fieldId: string, access: “hidden” / “read” / “edit” }> no
id body string no
name body string yes
recordRules body array<{ tableId: string, access: “read” / “edit”, where: array }> no

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { role: { id: string, key: “owner” / “admin” / “member” / “limited” / “guest” or null, builtin: boolean, name: string, capabilities: array, recordRules: array, fieldRules: array, version: integer, rank: integer, memberCount: integer, assignable: boolean }, changeId: integer }.

POST /roles/{roleId}/delete

Preview and delete a custom role, reassigning every member when in use.

Capability: core.roles.manage. Kind: destructive.

Field In Type Required
roleId path string yes
Idempotency-Key header string no
Srvo-Confirmation header string no
reassignTo body “owner” / “admin” / “member” / “limited” / “guest” or string no

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Srvo-Confirmation: Without it the call returns a preview and a token; send the token back to commit.

Output: { roleId: string, reassigned: integer, changeId: integer } or { preview: { summary: string, counts: object, warnings: array }, confirmationToken: string, expiresAt: string }.

GET /roles

List the roles: built-in roles with their capabilities, member counts and whether you may assign them.

Capability: core.roles.read. Kind: read.

No input fields.

Output: { items: array, customRolesSupported: boolean }.

PATCH /roles/{roleId}

Update a custom role. Built-in roles are immutable.

Capability: core.roles.manage. Kind: write.

Field In Type Required
roleId path string yes
Idempotency-Key header string no
baseVersion body integer yes
capabilities body array yes
fieldRules body array<{ tableId: string, fieldId: string, access: “hidden” / “read” / “edit” }> no
name body string yes
recordRules body array<{ tableId: string, access: “read” / “edit”, where: array }> no

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { role: { id: string, key: “owner” / “admin” / “member” / “limited” / “guest” or null, builtin: boolean, name: string, capabilities: array, recordRules: array, fieldRules: array, version: integer, rank: integer, memberCount: integer, assignable: boolean }, changeId: integer }.

GET /scripts/runs/{runId}

Read a SRVO Script run you started: status, output or error, CPU and SDK calls.

Capability: core.scripts.read. Kind: read.

Field In Type Required
runId path string yes

Output: { runId: string, status: “running” / “ok” / “error”, scriptHash: string, startedAt: string, finishedAt: string or null, output: null or boolean or number or string or array or object or null, error: { code: “LIMIT_CPU” / “LIMIT_MEMORY” / “LIMIT_WALL” / “LIMIT_STACK” / “LIMIT_OUTPUT” / “LIMIT_CALLS” / “INVALID_SCRIPT” / “SCRIPT_ERROR” / “BUSY” / “INTERNAL”, message: string or null } or null, usage: { cpuMs: number, wallMs: number, calls: integer } or null }.

POST /scripts/runs

Start a read-only SRVO Script run as you. Poll core.scripts.get for the result.

Capability: core.scripts.run. Kind: read.

Field In Type Required
args body unknown no
source body string yes

Output: { runId: string, status: “running” / “ok” / “error”, scriptHash: string, startedAt: string, finishedAt: string or null, output: null or boolean or number or string or array or object or null, error: { code: “LIMIT_CPU” / “LIMIT_MEMORY” / “LIMIT_WALL” / “LIMIT_STACK” / “LIMIT_OUTPUT” / “LIMIT_CALLS” / “INVALID_SCRIPT” / “SCRIPT_ERROR” / “BUSY” / “INTERNAL”, message: string or null } or null, usage: { cpuMs: number, wallMs: number, calls: integer } or null }.

POST /search/query

Search readable records, structure, note titles, member names and own Track entries. Empty queries return no recents.

Capability: core.self.read. Kind: read.

Field In Type Required
cursor body string no
limit body integer no
q body string yes
types body array<“record” / “table” / “dashboard” / “space” / “folder” / “view” / “note” / “member” / “time_entry”> or string no

Output: { groups: array, nextCursor: string or null, truncated: boolean }.

GET /me

Who am I: workspace, member, role, kind, and for agents the person they act for.

Capability: core.self.read. Kind: read.

No input fields.

Output: { tenantId: string, memberId: string, kind: “user” / “agent” / “integration” / “automation”, name: string, role: string, workspace: { name: string, slug: string or null }, onBehalfOf: string or null, modules: array, structureV2?: boolean }.

GET /taxonomies/{kind}/{id}/access

Who can use a Project, Client or Tag. Grant details need Manage and sharing authority; others see only their own rights.

Capability: core.taxonomies.read. Kind: read.

Field In Type Required
kind path “project” / “client” / “tag” yes
id path string yes

Output: { detailed: false, rights: { view: boolean, use: boolean, contribute: boolean, manage: boolean, delete: boolean }, sharing: { allowed: true } or { allowed: false, reason: “view_only” / “archived” / “source_read_only” / “not_delegated” / “scope_restricted” / “not_allowed” } } or { detailed: true, rights: { view: boolean, use: boolean, contribute: boolean, manage: boolean, delete: boolean }, sharing: { allowed: true } or { allowed: false, reason: “view_only” / “archived” / “source_read_only” / “not_delegated” / “scope_restricted” / “not_allowed” }, grants: array }.

POST /taxonomies/{kind}/{id}/access/revoke

Remove grants from a Project, Client or Tag. Preview, then confirm. The last manager cannot be removed.

Capability: core.taxonomies.write. Kind: destructive.

Field In Type Required
kind path “project” / “client” / “tag” yes
id path string yes
Idempotency-Key header string yes
Srvo-Confirmation header string no
baseVersion body integer yes
grantIds body array yes

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Srvo-Confirmation: Without it the call returns a preview and a token; send the token back to commit.

Output: { access: { detailed: false, rights: object, sharing: object } or { detailed: true, rights: object, sharing: object, grants: array }, version: integer, policyEpoch: integer, changeId: integer } or { preview: { summary: string, counts: object, warnings: array }, confirmationToken: string, expiresAt: string }.

POST /taxonomies/{kind}/{id}/access

Set one member’s, team’s or role’s rights on a Project, Client or Tag (preset or exact rights). Preview, then confirm. Needs Manage and sharing authority.

Capability: core.taxonomies.write. Kind: destructive.

Field In Type Required
kind path “project” / “client” / “tag” yes
id path string yes
Idempotency-Key header string yes
Srvo-Confirmation header string no
baseVersion body integer yes
delegableRights body array<“view” / “use” / “contribute” / “manage” / “delete”> no
effect body “allow” / “deny” no
preset body “member” / “contributor” / “manager” no
rights body array<“view” / “use” / “contribute” / “manage” / “delete”> no
subject body { kind: “member”, id: string } or { kind: “team”, id: string } or { kind: “role”, id: “owner” / “admin” / “member” / “limited” / “guest” or string } or { kind: “all_members” } yes

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Srvo-Confirmation: Without it the call returns a preview and a token; send the token back to commit.

Output: { access: { detailed: false, rights: object, sharing: object } or { detailed: true, rights: object, sharing: object, grants: array }, version: integer, policyEpoch: integer, changeId: integer } or { preview: { summary: string, counts: object, warnings: array }, confirmationToken: string, expiresAt: string }.

POST /taxonomies/{kind}/{id}/archive

Archive or unarchive a Project, Client or Tag. Archived entries keep their links and history but cannot be newly used. Needs Manage.

Capability: core.taxonomies.write. Kind: write.

Field In Type Required
kind path “project” / “client” / “tag” yes
id path string yes
Idempotency-Key header string yes
archived body boolean yes
baseVersion body integer yes

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { entry: { id: string, label: string or null, color: “gray” / “red” / “orange” / “amber” / “green” / “teal” / “cyan” / “sky” / “blue” / “indigo” / “purple” / “pink” or null, createdBy: object, createdFor: object, createdAt: string, editedBy: object, editedAt: string, version: integer, archived: boolean, visibility: “members” / “workspace” / “team” / “private”, rights: object, kind: “project”, tableId: string, fields: object } or { id: string, label: string or null, color: “gray” / “red” / “orange” / “amber” / “green” / “teal” / “cyan” / “sky” / “blue” / “indigo” / “purple” / “pink” or null, createdBy: object, createdFor: object, createdAt: string, editedBy: object, editedAt: string, version: integer, archived: boolean, visibility: “members” / “workspace” / “team” / “private”, rights: object, kind: “client”, tableId: string, fields: object } or { id: string, label: string or null, color: “gray” / “red” / “orange” / “amber” / “green” / “teal” / “cyan” / “sky” / “blue” / “indigo” / “purple” / “pink” or null, createdBy: object, createdFor: object, createdAt: string, editedBy: object, editedAt: string, version: integer, archived: boolean, visibility: “members” / “workspace” / “team” / “private”, rights: object, kind: “tag” }, changeId: integer }.

POST /taxonomies/{kind}/capabilities

What you can do now: create this kind, your rights on one entry, and whether you can edit a source. Advisory; writes recheck.

Capability: core.taxonomies.read. Kind: read.

Field In Type Required
kind path “project” / “client” / “tag” yes
id body string no
source body { module: string, kind: string, id: string } no

Output: { kind: “project” / “client” / “tag”, policyEpoch: integer, create: { allowed: true } or { allowed: false, reason: “view_only” / “archived” / “source_read_only” / “not_delegated” / “scope_restricted” / “not_allowed” }, entry?: { ref: object, version: integer, rights: object, sharing: object }, source?: { ref: object, version: integer, edit: object } }.

POST /taxonomies/{kind}

Create a Project, Client or Tag. You become its manager; default visibility is members-only (Projects/Clients) or workspace (Tags).

Capability: core.taxonomies.write. Kind: write.

Field In Type Required
kind path “project” / “client” / “tag” yes
Idempotency-Key header string yes
color body “gray” / “red” / “orange” / “amber” / “green” / “teal” / “cyan” / “sky” / “blue” / “indigo” / “purple” / “pink” no
fields body object no
id body string no
name body string yes
teamIds body array no
visibility body “members” / “workspace” / “team” / “private” no

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { entry: { id: string, label: string or null, color: “gray” / “red” / “orange” / “amber” / “green” / “teal” / “cyan” / “sky” / “blue” / “indigo” / “purple” / “pink” or null, createdBy: object, createdFor: object, createdAt: string, editedBy: object, editedAt: string, version: integer, archived: boolean, visibility: “members” / “workspace” / “team” / “private”, rights: object, kind: “project”, tableId: string, fields: object } or { id: string, label: string or null, color: “gray” / “red” / “orange” / “amber” / “green” / “teal” / “cyan” / “sky” / “blue” / “indigo” / “purple” / “pink” or null, createdBy: object, createdFor: object, createdAt: string, editedBy: object, editedAt: string, version: integer, archived: boolean, visibility: “members” / “workspace” / “team” / “private”, rights: object, kind: “client”, tableId: string, fields: object } or { id: string, label: string or null, color: “gray” / “red” / “orange” / “amber” / “green” / “teal” / “cyan” / “sky” / “blue” / “indigo” / “purple” / “pink” or null, createdBy: object, createdFor: object, createdAt: string, editedBy: object, editedAt: string, version: integer, archived: boolean, visibility: “members” / “workspace” / “team” / “private”, rights: object, kind: “tag” }, changeId: integer }.

POST /taxonomies/{kind}/{id}/delete

Move an unreferenced Project, Client or Tag to the trash. Preview lists references; referenced entries must be archived instead. Needs Manage and Delete.

Capability: core.taxonomies.write. Kind: destructive.

Field In Type Required
kind path “project” / “client” / “tag” yes
id path string yes
Idempotency-Key header string yes
Srvo-Confirmation header string no
baseVersion body integer yes

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Srvo-Confirmation: Without it the call returns a preview and a token; send the token back to commit.

Output: { ref: { kind: “project” / “client” / “tag”, id: string }, changeId: integer } or { preview: { summary: string, counts: object, warnings: array }, confirmationToken: string, expiresAt: string }.

GET /taxonomies/{kind}/{id}

Read one Project, Client or Tag with creator/editor details and your current rights.

Capability: core.taxonomies.read. Kind: read.

Field In Type Required
kind path “project” / “client” / “tag” yes
id path string yes

Output: { entry: { id: string, label: string or null, color: “gray” / “red” / “orange” / “amber” / “green” / “teal” / “cyan” / “sky” / “blue” / “indigo” / “purple” / “pink” or null, createdBy: object, createdFor: object, createdAt: string, editedBy: object, editedAt: string, version: integer, archived: boolean, visibility: “members” / “workspace” / “team” / “private”, rights: object, kind: “project”, tableId: string, fields: object } or { id: string, label: string or null, color: “gray” / “red” / “orange” / “amber” / “green” / “teal” / “cyan” / “sky” / “blue” / “indigo” / “purple” / “pink” or null, createdBy: object, createdFor: object, createdAt: string, editedBy: object, editedAt: string, version: integer, archived: boolean, visibility: “members” / “workspace” / “team” / “private”, rights: object, kind: “client”, tableId: string, fields: object } or { id: string, label: string or null, color: “gray” / “red” / “orange” / “amber” / “green” / “teal” / “cyan” / “sky” / “blue” / “indigo” / “purple” / “pink” or null, createdBy: object, createdFor: object, createdAt: string, editedBy: object, editedAt: string, version: integer, archived: boolean, visibility: “members” / “workspace” / “team” / “private”, rights: object, kind: “tag” } }.

POST /taxonomies/{kind}/{id}/history/list

Paged history of one Project, Client or Tag under your current View and field masks. Access details need Manage.

Capability: core.taxonomies.read. Kind: read.

Field In Type Required
kind path “project” / “client” / “tag” yes
id path string yes
cursor body string no
eventTypes body array<“create” / “rename” / “fields” / “contribution_added” / “link_added” / “link_removed” / “visibility” / “access” / “access_effect” / “archive” / “unarchive” / “trash” / “restore” / “delete_requested” / “recovery” / “migration_baseline”> no
limit body integer no

Output: { items: array, nextCursor: string or null }.

GET /taxonomies/{kind}

List Projects, Clients or Tags you can view. Filters (Made by me, origin, archive, search) apply after access, before paging.

Capability: core.taxonomies.read. Kind: read.

Field In Type Required
kind path “project” / “client” / “tag” yes
query query string no
madeByMe query boolean no
origin query “human” / “ai” / “integration” / “automation” / “import” / “migration” no
archived query “active” / “archived” / “all” no
cursor query string no
limit query integer no

Output: { items: array, nextCursor: string or null }.

POST /taxonomies/{kind}/picker

Choices for a Project, Client or Tag picker. Viewable entries without Use are returned disabled with a reason.

Capability: core.taxonomies.read. Kind: read.

Field In Type Required
kind path “project” / “client” / “tag” yes
archived body “active” / “archived” / “all” no
cursor body string no
limit body integer no
madeByMe body boolean no
origin body “human” / “ai” / “integration” / “automation” / “import” / “migration” no
query body string no
source body { module: string, kind: string, id: string } no

Output: { items: array, nextCursor: string or null }.

POST /taxonomies/{kind}/{id}/recover

Make yourself manager of a private Project, Client or Tag that no one can manage. Owner (or owner-delegated admin) only; needs a reason; audited. Private parents stay closed.

Capability: core.taxonomies.write. Kind: destructive.

Field In Type Required
kind path “project” / “client” / “tag” yes
id path string yes
Idempotency-Key header string yes
Srvo-Confirmation header string no
baseVersion body integer yes
reason body string yes

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Srvo-Confirmation: Without it the call returns a preview and a token; send the token back to commit.

Output: { entry: { id: string, label: string or null, color: “gray” / “red” / “orange” / “amber” / “green” / “teal” / “cyan” / “sky” / “blue” / “indigo” / “purple” / “pink” or null, createdBy: object, createdFor: object, createdAt: string, editedBy: object, editedAt: string, version: integer, archived: boolean, visibility: “members” / “workspace” / “team” / “private”, rights: object, kind: “project”, tableId: string, fields: object } or { id: string, label: string or null, color: “gray” / “red” / “orange” / “amber” / “green” / “teal” / “cyan” / “sky” / “blue” / “indigo” / “purple” / “pink” or null, createdBy: object, createdFor: object, createdAt: string, editedBy: object, editedAt: string, version: integer, archived: boolean, visibility: “members” / “workspace” / “team” / “private”, rights: object, kind: “client”, tableId: string, fields: object } or { id: string, label: string or null, color: “gray” / “red” / “orange” / “amber” / “green” / “teal” / “cyan” / “sky” / “blue” / “indigo” / “purple” / “pink” or null, createdBy: object, createdFor: object, createdAt: string, editedBy: object, editedAt: string, version: integer, archived: boolean, visibility: “members” / “workspace” / “team” / “private”, rights: object, kind: “tag” } or null, changeId: integer, version: integer, policyEpoch: integer } or { preview: { summary: string, counts: object, warnings: array }, confirmationToken: string, expiresAt: string }.

GET /taxonomy-recovery

Private Projects, Clients and Tags that no one can manage any more. Owner (or owner-delegated admin) only; needs a reason and is audited. Returns IDs and creation metadata, never names.

Capability: core.taxonomies.read. Kind: read.

Field In Type Required
kind query “project” / “client” / “tag” no
reason query string yes
cursor query string no
limit query integer no

Output: { items: array, nextCursor: string or null }.

GET /taxonomy-settings

Who may create Projects, Clients and Tags. Owners/admins see the configured roles, members and teams; others see what they can create.

Capability: core.taxonomies.read. Kind: read.

No input fields.

Output: { version: integer, schemaVersion: 1, detailed: false, create: { project: object, client: object, tag: object } } or { version: integer, schemaVersion: 1, detailed: true, creation: { project: object, client: object, tag: object } }.

PATCH /taxonomy-settings

Choose which roles, members and teams may create one taxonomy kind. Human owners/admins only; never changes existing entry access.

Capability: core.taxonomies.write. Kind: write.

Field In Type Required
Idempotency-Key header string yes
baseVersion body integer yes
creationPolicy body { roles: array<“owner” / “admin” / “member” / “limited” / “guest” or string>, memberIds: array, teamIds: array } yes
taxonomy body “project” / “client” / “tag” yes

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { settings: { version: integer, schemaVersion: 1, detailed: false, create: object } or { version: integer, schemaVersion: 1, detailed: true, creation: object }, policyEpoch: integer, changeId: integer }.

PATCH /taxonomies/{kind}/{id}

Rename a Project, Client or Tag, change a Tag colour, or edit permitted fields. Needs Manage.

Capability: core.taxonomies.write. Kind: write.

Field In Type Required
kind path “project” / “client” / “tag” yes
id path string yes
Idempotency-Key header string yes
baseVersion body integer yes
patch body { name?: string, color?: “gray” / “red” / “orange” / “amber” / “green” / “teal” / “cyan” / “sky” / “blue” / “indigo” / “purple” / “pink”, fields?: object } yes

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { entry: { id: string, label: string or null, color: “gray” / “red” / “orange” / “amber” / “green” / “teal” / “cyan” / “sky” / “blue” / “indigo” / “purple” / “pink” or null, createdBy: object, createdFor: object, createdAt: string, editedBy: object, editedAt: string, version: integer, archived: boolean, visibility: “members” / “workspace” / “team” / “private”, rights: object, kind: “project”, tableId: string, fields: object } or { id: string, label: string or null, color: “gray” / “red” / “orange” / “amber” / “green” / “teal” / “cyan” / “sky” / “blue” / “indigo” / “purple” / “pink” or null, createdBy: object, createdFor: object, createdAt: string, editedBy: object, editedAt: string, version: integer, archived: boolean, visibility: “members” / “workspace” / “team” / “private”, rights: object, kind: “client”, tableId: string, fields: object } or { id: string, label: string or null, color: “gray” / “red” / “orange” / “amber” / “green” / “teal” / “cyan” / “sky” / “blue” / “indigo” / “purple” / “pink” or null, createdBy: object, createdFor: object, createdAt: string, editedBy: object, editedAt: string, version: integer, archived: boolean, visibility: “members” / “workspace” / “team” / “private”, rights: object, kind: “tag” }, changeId: integer }.

POST /taxonomies/{kind}/{id}/visibility

Change who sees a Project, Client or Tag by default: members-only, a team, the workspace, or private. Preview, then confirm.

Capability: core.taxonomies.write. Kind: destructive.

Field In Type Required
kind path “project” / “client” / “tag” yes
id path string yes
Idempotency-Key header string yes
Srvo-Confirmation header string no
baseVersion body integer yes
teamIds body array no
visibility body “members” / “workspace” / “team” / “private” yes

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Srvo-Confirmation: Without it the call returns a preview and a token; send the token back to commit.

Output: { entry: { id: string, label: string or null, color: “gray” / “red” / “orange” / “amber” / “green” / “teal” / “cyan” / “sky” / “blue” / “indigo” / “purple” / “pink” or null, createdBy: object, createdFor: object, createdAt: string, editedBy: object, editedAt: string, version: integer, archived: boolean, visibility: “members” / “workspace” / “team” / “private”, rights: object, kind: “project”, tableId: string, fields: object } or { id: string, label: string or null, color: “gray” / “red” / “orange” / “amber” / “green” / “teal” / “cyan” / “sky” / “blue” / “indigo” / “purple” / “pink” or null, createdBy: object, createdFor: object, createdAt: string, editedBy: object, editedAt: string, version: integer, archived: boolean, visibility: “members” / “workspace” / “team” / “private”, rights: object, kind: “client”, tableId: string, fields: object } or { id: string, label: string or null, color: “gray” / “red” / “orange” / “amber” / “green” / “teal” / “cyan” / “sky” / “blue” / “indigo” / “purple” / “pink” or null, createdBy: object, createdFor: object, createdAt: string, editedBy: object, editedAt: string, version: integer, archived: boolean, visibility: “members” / “workspace” / “team” / “private”, rights: object, kind: “tag” } or null, changeId: integer, version: integer, policyEpoch: integer } or { preview: { summary: string, counts: object, warnings: array }, confirmationToken: string, expiresAt: string }.

POST /teams

Create a team (open or closed), optionally with its first members.

Capability: core.teams.manage. Kind: write.

Field In Type Required
Idempotency-Key header string no
id body string no
memberIds body array no
name body string yes
visibility body “open” / “closed” no

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { team: { id: string, name: string, visibility: “open” / “closed”, memberIds: array, isMember: boolean, createdAt: string, version: integer }, changeId: integer }.

POST /teams/{teamId}/delete

Delete a team that has no spaces left; its memberships go with it.

Capability: core.teams.manage. Kind: destructive.

Field In Type Required
teamId path string yes
Idempotency-Key header string no
Srvo-Confirmation header string no

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Srvo-Confirmation: Without it the call returns a preview and a token; send the token back to commit.

Output: { team: { id: string, name: string, visibility: “open” / “closed”, memberIds: array, isMember: boolean, createdAt: string, version: integer }, changeId: integer } or { preview: { summary: string, counts: object, warnings: array }, confirmationToken: string, expiresAt: string }.

GET /teams

List teams: open ones, the closed ones you’re in (team managers see all).

Capability: core.teams.read. Kind: read.

No input fields.

Output: { items: array }.

POST /teams/{teamId}/members

Add a member to a team. Without team management rights you can only join an open team yourself.

Capability: core.teams.join. Kind: write.

Field In Type Required
teamId path string yes
Idempotency-Key header string no
memberId body string yes

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { team: { id: string, name: string, visibility: “open” / “closed”, memberIds: array, isMember: boolean, createdAt: string, version: integer }, changeId: integer }.

DELETE /teams/{teamId}/members/{memberId}

Remove a member from a team. Without team management rights you can only leave a team yourself.

Capability: core.teams.join. Kind: write.

Field In Type Required
teamId path string yes
memberId path string yes
Idempotency-Key header string no

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { team: { id: string, name: string, visibility: “open” / “closed”, memberIds: array, isMember: boolean, createdAt: string, version: integer }, changeId: integer }.

PATCH /teams/{teamId}

Rename a team or switch it between open and closed.

Capability: core.teams.manage. Kind: write.

Field In Type Required
teamId path string yes
Idempotency-Key header string no
name body string no
visibility body “open” / “closed” no

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { team: { id: string, name: string, visibility: “open” / “closed”, memberIds: array, isMember: boolean, createdAt: string, version: integer }, changeId: integer }.

GET /trash/records

Return readable trashed records under live parents. Pass optional cursor/limit; follow nextCursor. Structure trash uses listTrashedItems.

Capability: core.self.read. Kind: read.

Field In Type Required
cursor query string no
limit query integer no

Output: { items: array, nextCursor: string or null }.

files

POST /files/{fileId}/download

Sign a five-minute attachment URL after a current permission check.

Capability: files.entries.read. Kind: read.

Field In Type Required
fileId path string yes
versionId body string no

Output: { url: string, headers: object, expiresAt: string }.

POST /files/{fileId}/copy

Copy a readable file into a writable folder using storage-side copy.

Capability: files.entries.edit. Kind: write.

Field In Type Required
fileId path string yes
folderId body string or null no
spaceId body string yes

Output: { file: { id: string, spaceId: string, folderId: string or null, parentVisible?: boolean, name: string, mime: string, size: number, currentVersionId: string or null, version: number, deletedAt: string or null, updatedAt: string, status: “pending” / “scanning” / “ready” / “failed”, scanStatus: “pending” / “clean” / “infected”, createdBy: string or null } }.

GET /files/{fileId}

Get one visible file’s metadata (name, type, size, folder, status, version). Never returns file bytes or URLs.

Capability: files.entries.read. Kind: read.

Field In Type Required
fileId path string yes

Output: { file: { id: string, spaceId: string, folderId: string or null, parentVisible?: boolean, name: string, mime: string, size: number, currentVersionId: string or null, version: number, deletedAt: string or null, updatedAt: string, status: “pending” / “scanning” / “ready” / “failed”, scanStatus: “pending” / “clean” / “infected”, createdBy: string or null } }.

POST /files/{fileId}/move

Move a file after checking its folder permission.

Capability: files.entries.edit. Kind: write.

Field In Type Required
fileId path string yes
baseVersion body integer yes
confirmToken body string no
folderId body string or null no
spaceId body string yes

Output: { file: { id: string, spaceId: string, folderId: string or null, parentVisible?: boolean, name: string, mime: string, size: number, currentVersionId: string or null, version: number, deletedAt: string or null, updatedAt: string, status: “pending” / “scanning” / “ready” / “failed”, scanStatus: “pending” / “clean” / “infected”, createdBy: string or null } } or { preview: { gains: array, losses: array, itemCount: integer }, confirmToken: string }.

POST /files/{fileId}/purge

Permanently delete a trashed file (bytes are removed after retention). Call without confirmationToken to preview, then with the returned token to commit.

Capability: files.entries.edit. Kind: destructive.

Field In Type Required
fileId path string yes
Srvo-Confirmation header string no
baseVersion body integer yes

Srvo-Confirmation: Without it the call returns a preview and a token; send the token back to commit.

Output: { file: { id: string, spaceId: string, folderId: string or null, parentVisible?: boolean, name: string, mime: string, size: number, currentVersionId: string or null, version: number, deletedAt: string or null, updatedAt: string, status: “pending” / “scanning” / “ready” / “failed”, scanStatus: “pending” / “clean” / “infected”, createdBy: string or null } } or { preview: { summary: string, counts: object, warnings: array }, confirmationToken: string, expiresAt: string }.

POST /files/{fileId}/rename

Rename a file after checking its folder permission.

Capability: files.entries.edit. Kind: write.

Field In Type Required
fileId path string yes
baseVersion body integer yes
name body string yes

Output: { file: { id: string, spaceId: string, folderId: string or null, parentVisible?: boolean, name: string, mime: string, size: number, currentVersionId: string or null, version: number, deletedAt: string or null, updatedAt: string, status: “pending” / “scanning” / “ready” / “failed”, scanStatus: “pending” / “clean” / “infected”, createdBy: string or null } }.

POST /files/{fileId}/restore

Restore a file after checking its folder permission.

Capability: files.entries.edit. Kind: write.

Field In Type Required
fileId path string yes
baseVersion body integer yes
confirmToken body string no

Output: { file: { id: string, spaceId: string, folderId: string or null, parentVisible?: boolean, name: string, mime: string, size: number, currentVersionId: string or null, version: number, deletedAt: string or null, updatedAt: string, status: “pending” / “scanning” / “ready” / “failed”, scanStatus: “pending” / “clean” / “infected”, createdBy: string or null } } or { preview: { destination: “privateRoot”, parentId: null, ownerId: string, itemCount: integer }, confirmToken: string }.

POST /files/{fileId}/trash

Trash a file after checking its folder permission.

Capability: files.entries.edit. Kind: write.

Field In Type Required
fileId path string yes
baseVersion body integer yes

Output: { file: { id: string, spaceId: string, folderId: string or null, parentVisible?: boolean, name: string, mime: string, size: number, currentVersionId: string or null, version: number, deletedAt: string or null, updatedAt: string, status: “pending” / “scanning” / “ready” / “failed”, scanStatus: “pending” / “clean” / “infected”, createdBy: string or null } }.

POST /files/folders

Create a Files folder in the shared item tree.

Capability: files.entries.edit. Kind: write.

Field In Type Required
name body string yes
parentId body string or null no
spaceId body string yes
visibility body “inherit” / “private” no

Output: { folder: { id: string, spaceId: string, parentId: string or null, parentVisible?: boolean, name: string, version: number, updatedAt: string, deletedAt: string or null, summary?: object } }.

GET /files/contents/list

List visible folders first, then files, with sorting and paging.

Capability: files.entries.read. Kind: read.

Field In Type Required
folderId query string or null no
spaceId query string no
parentId query string or null no
section query “all” / “workspace” / “shared” / “private” / “favourites” / “recent” / “sharedWithMe” no
sort query “name” / “modified” / “size” no
direction query “asc” / “desc” no
offset query integer no
limit query integer no

Output: { folders: array, files: array, hasMore: boolean, uploadsEnabled: boolean, items?: array, summary?: { bytes: number, files: integer, notes: integer, boards: integer } }.

POST /files/folders/{folderId}/move

Move a Files folder.

Capability: files.entries.edit. Kind: write.

Field In Type Required
folderId path string yes
baseVersion body integer yes
confirmToken body string no
parentId body string or null yes

Output: { folder: { id: string, spaceId: string, parentId: string or null, parentVisible?: boolean, name: string, version: number, updatedAt: string, deletedAt: string or null, summary?: object } } or { preview: { gains: array, losses: array, itemCount: integer }, confirmToken: string }.

GET /files/path/{itemId}

Get the folder path (breadcrumb) from the root to a visible file or folder. Ancestors you cannot see come back with null id and name.

Capability: files.entries.read. Kind: read.

Field In Type Required
itemId path string yes

Output: { path: array }.

POST /files/folders/{folderId}/purge

Permanently delete a trashed Files folder and its contents you can edit (bytes are removed after retention). Call without confirmationToken to preview, then with the returned token to commit.

Capability: files.entries.edit. Kind: destructive.

Field In Type Required
folderId path string yes
Srvo-Confirmation header string no
baseVersion body integer yes

Srvo-Confirmation: Without it the call returns a preview and a token; send the token back to commit.

Output: { folder: { id: string, spaceId: string, parentId: string or null, parentVisible?: boolean, name: string, version: number, updatedAt: string, deletedAt: string or null, summary?: object } } or { preview: { summary: string, counts: object, warnings: array }, confirmationToken: string, expiresAt: string }.

POST /files/folders/{folderId}/rename

Rename a Files folder.

Capability: files.entries.edit. Kind: write.

Field In Type Required
folderId path string yes
baseVersion body integer yes
name body string yes

Output: { folder: { id: string, spaceId: string, parentId: string or null, parentVisible?: boolean, name: string, version: number, updatedAt: string, deletedAt: string or null, summary?: object } }.

POST /files/folders/{folderId}/restore

Restore a Files folder.

Capability: files.entries.edit. Kind: write.

Field In Type Required
folderId path string yes
baseVersion body integer yes
confirmToken body string no

Output: { folder: { id: string, spaceId: string, parentId: string or null, parentVisible?: boolean, name: string, version: number, updatedAt: string, deletedAt: string or null, summary?: object } } or { preview: { destination: “privateRoot”, parentId: null, ownerId: string, itemCount: integer }, confirmToken: string }.

POST /files/folders/{folderId}/trash

Trash a Files folder.

Capability: files.entries.edit. Kind: write.

Field In Type Required
folderId path string yes
baseVersion body integer yes

Output: { folder: { id: string, spaceId: string, parentId: string or null, parentVisible?: boolean, name: string, version: number, updatedAt: string, deletedAt: string or null, summary?: object } }.

POST /files/{fileId}/preview

Sign an allowlisted image/PDF preview; other types download as attachments.

Capability: files.entries.read. Kind: read.

Field In Type Required
fileId path string yes
versionId body string no

Output: { url: string, headers: object, expiresAt: string }.

POST /files/roots/ensure

Create a usable Files root in a writable space, or return the existing root.

Capability: files.entries.edit. Kind: write.

Field In Type Required
spaceId body string yes

Output: { folder: { id: string, spaceId: string, parentId: string or null, parentVisible?: boolean, name: string, version: number, updatedAt: string, deletedAt: string or null, summary?: object } }.

POST /shares

Create a Transfer package or file request link. Returns the token once.

Capability: files.entries.edit. Kind: write.

Field In Type Required
audience body “restricted” / “workspace” / “anyone” no
disableDownload body boolean no
downloadLimit body integer no
expiresInDays body integer no
fileIds body array no
folderId body string or null no
kind body “transfer” / “request” yes
message body string no
password body string no
recipients body array no
role body “viewer” / “commenter” / “editor” no
spaceId body string or null no
targetItemId body string no
title body string no

Output: { share: { id: string, kind: “transfer” / “request”, spaceId: string or null, targetItemId?: string, audience?: “restricted” / “workspace” / “anyone”, role?: “viewer” / “commenter” / “editor”, disableDownload?: boolean, folderId: string or null, title: string, message: string, recipients: array, expiresAt: string, hasPassword: boolean, downloadLimit: number or null, downloadCount: number, uploadCount: number, viewCount: number, revokedAt: string or null, createdAt: string, createdBy: string, status: “active” / “expired” / “revoked” / “limit”, files: array }, token: string }.

GET /shares/{shareId}

Read one of my shares with its view, download and upload history.

Capability: files.entries.read. Kind: read.

Field In Type Required
shareId path string yes

Output: { share: { id: string, kind: “transfer” / “request”, spaceId: string or null, targetItemId?: string, audience?: “restricted” / “workspace” / “anyone”, role?: “viewer” / “commenter” / “editor”, disableDownload?: boolean, folderId: string or null, title: string, message: string, recipients: array, expiresAt: string, hasPassword: boolean, downloadLimit: number or null, downloadCount: number, uploadCount: number, viewCount: number, revokedAt: string or null, createdAt: string, createdBy: string, status: “active” / “expired” / “revoked” / “limit”, files: array }, events: array }.

GET /shares

List my Transfer packages and file requests, newest first.

Capability: files.entries.read. Kind: read.

Field In Type Required
kind query “transfer” / “request” no
limit query integer no

Output: { shares: array }.

GET /shares/item/{targetItemId}

List all live links on an item I can manage.

Capability: files.entries.read. Kind: read.

Field In Type Required
targetItemId path string yes

Output: { shares: array }.

POST /shares/{shareId}/revoke

Revoke a share now. The public link stops at once.

Capability: files.entries.edit. Kind: write.

Field In Type Required
shareId path string yes

Output: { share: { id: string, kind: “transfer” / “request”, spaceId: string or null, targetItemId?: string, audience?: “restricted” / “workspace” / “anyone”, role?: “viewer” / “commenter” / “editor”, disableDownload?: boolean, folderId: string or null, title: string, message: string, recipients: array, expiresAt: string, hasPassword: boolean, downloadLimit: number or null, downloadCount: number, uploadCount: number, viewCount: number, revokedAt: string or null, createdAt: string, createdBy: string, status: “active” / “expired” / “revoked” / “limit”, files: array } }.

POST /shares/{shareId}/update

Update a v2 item link’s audience, role, password, expiry and download setting.

Capability: files.entries.edit. Kind: write.

Field In Type Required
shareId path string yes
audience body “restricted” / “workspace” / “anyone” no
disableDownload body boolean no
expiresInDays body integer no
password body string or null no
role body “viewer” / “commenter” / “editor” no

Output: { share: { id: string, kind: “transfer” / “request”, spaceId: string or null, targetItemId?: string, audience?: “restricted” / “workspace” / “anyone”, role?: “viewer” / “commenter” / “editor”, disableDownload?: boolean, folderId: string or null, title: string, message: string, recipients: array, expiresAt: string, hasPassword: boolean, downloadLimit: number or null, downloadCount: number, uploadCount: number, viewCount: number, revokedAt: string or null, createdAt: string, createdBy: string, status: “active” / “expired” / “revoked” / “limit”, files: array } }.

GET /files/storage/usage

Read workspace storage usage, including versions, trash and pending reservations.

Capability: files.storage.manage. Kind: read.

No input fields.

Output: { usedBytes: number, reservedBytes: number, quotaBytes: number or null }.

GET /files/trash/list

List trashed Files folders and files you could restore. Paginated with offset and limit (max 200); hasMore says whether another page exists.

Capability: files.entries.read. Kind: read.

Field In Type Required
offset query integer no
limit query integer no

Output: { folders: array, files: array, hasMore: boolean }.

POST /files/uploads/{uploadId}/abort

Abort a direct upload session owned by the caller.

Capability: files.entries.edit. Kind: write.

Field In Type Required
uploadId path string yes

Output: { file?: { id: string, spaceId: string, folderId: string or null, parentVisible?: boolean, name: string, mime: string, size: number, currentVersionId: string or null, version: number, deletedAt: string or null, updatedAt: string, status: “pending” / “scanning” / “ready” / “failed”, scanStatus: “pending” / “clean” / “infected”, createdBy: string or null }, parts?: array, aborted?: boolean }.

POST /files/uploads

Reserve storage and sign a direct upload. Never send file bytes to this endpoint.

Capability: files.entries.edit. Kind: write.

Field In Type Required
collision body “rename” / “replace” no
contentType body string yes
folderId body string or null no
name body string yes
sha256 body string no
size body integer yes
spaceId body string yes

Output: { uploadId: string, fileId: string, versionId: string, partSize: number, parts: array, multipart: boolean }.

POST /files/uploads/{uploadId}/complete

Complete a direct upload session owned by the caller.

Capability: files.entries.edit. Kind: write.

Field In Type Required
uploadId path string yes
etag body string no

Output: { file?: { id: string, spaceId: string, folderId: string or null, parentVisible?: boolean, name: string, mime: string, size: number, currentVersionId: string or null, version: number, deletedAt: string or null, updatedAt: string, status: “pending” / “scanning” / “ready” / “failed”, scanStatus: “pending” / “clean” / “infected”, createdBy: string or null }, parts?: array, aborted?: boolean }.

POST /files/uploads/{uploadId}/part

Part a direct upload session owned by the caller.

Capability: files.entries.edit. Kind: write.

Field In Type Required
uploadId path string yes
part body { n: integer, etag: string, size: integer } yes

Output: { file?: { id: string, spaceId: string, folderId: string or null, parentVisible?: boolean, name: string, mime: string, size: number, currentVersionId: string or null, version: number, deletedAt: string or null, updatedAt: string, status: “pending” / “scanning” / “ready” / “failed”, scanStatus: “pending” / “clean” / “infected”, createdBy: string or null }, parts?: array, aborted?: boolean }.

POST /files/uploads/{uploadId}/urls

Urls a direct upload session owned by the caller.

Capability: files.entries.edit. Kind: write.

Field In Type Required
uploadId path string yes
parts body array yes

Output: { file?: { id: string, spaceId: string, folderId: string or null, parentVisible?: boolean, name: string, mime: string, size: number, currentVersionId: string or null, version: number, deletedAt: string or null, updatedAt: string, status: “pending” / “scanning” / “ready” / “failed”, scanStatus: “pending” / “clean” / “infected”, createdBy: string or null }, parts?: array, aborted?: boolean }.

GET /files/{fileId}/versions

List a visible file’s retained versions.

Capability: files.entries.read. Kind: read.

Field In Type Required
fileId path string yes

Output: { versions: array }.

POST /files/{fileId}/versions/{versionId}/restore

Restore a clean retained version without overwriting its bytes.

Capability: files.entries.edit. Kind: write.

Field In Type Required
fileId path string yes
versionId path string yes
baseVersion body integer yes

Output: { file: { id: string, spaceId: string, folderId: string or null, parentVisible?: boolean, name: string, mime: string, size: number, currentVersionId: string or null, version: number, deletedAt: string or null, updatedAt: string, status: “pending” / “scanning” / “ready” / “failed”, scanStatus: “pending” / “clean” / “infected”, createdBy: string or null } }.

flows

POST /flows

Create a disabled flow with an immutable version.

Capability: flows.edit. Kind: write.

Field In Type Required
Idempotency-Key header string yes
definition body { schemaVersion: 1, id: string, version: integer, name: string, trigger: { type: “record”, event: “created” / “updated” / “matching”, tableId: string, filter?: object, fieldId?: string, from?: object, to?: object } or { type: “track”, clientId?: string, projectId?: string } or { type: “schedule”, cron: string, timeZone: string, hungarianHolidays?: “include” / “skip-non-working-days” } or { type: “webhook”, method: “GET” / “POST” / “PUT” / “PATCH” / “DELETE”, payloadSchema: object } or { type: “inbound-email”, connectionId?: string } or { type: “form-submitted”, formId: string } or { type: “manual” } or { type: “flow”, flowId: string }, entry: string, steps: object } yes
runAs body string no

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { id: string, name: string, enabled: boolean, version: integer, definition: { schemaVersion: 1, id: string, version: integer, name: string, trigger: object, entry: string, steps: object }, createdBy: string, runAs: string, trashedAt: string or null, createdAt: string }.

POST /flows/{flowId}/disable

disable a flow.

Capability: flows.edit. Kind: write.

Field In Type Required
flowId path string yes
Idempotency-Key header string yes

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { id: string, name: string, enabled: boolean, version: integer, definition: { schemaVersion: 1, id: string, version: integer, name: string, trigger: object, entry: string, steps: object }, createdBy: string, runAs: string, trashedAt: string or null, createdAt: string }.

POST /flows/{flowId}/email/create

Give an email-triggered flow a new inbound address (replaces the old one). Returns its local part.

Capability: flows.edit. Kind: write.

Field In Type Required
flowId path string yes
Idempotency-Key header string yes

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { localPart?: string, ok: true }.

POST /flows/{flowId}/email/disable

Remove a flow’s inbound email address.

Capability: flows.edit. Kind: write.

Field In Type Required
flowId path string yes
Idempotency-Key header string yes

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { localPart?: string, ok: true }.

POST /flows/{flowId}/enable

enable a flow.

Capability: flows.edit. Kind: write.

Field In Type Required
flowId path string yes
Idempotency-Key header string yes

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { id: string, name: string, enabled: boolean, version: integer, definition: { schemaVersion: 1, id: string, version: integer, name: string, trigger: object, entry: string, steps: object }, createdBy: string, runAs: string, trashedAt: string or null, createdAt: string }.

GET /flows/{flowId}

Get a flow definition.

Capability: flows.edit. Kind: read.

Field In Type Required
flowId path string yes

Output: { id: string, name: string, enabled: boolean, version: integer, definition: { schemaVersion: 1, id: string, version: integer, name: string, trigger: object, entry: string, steps: object }, createdBy: string, runAs: string, trashedAt: string or null, createdAt: string }.

GET /flows

List workspace flows.

Capability: flows.edit. Kind: read.

Field In Type Required
trash query boolean no

Output: { items: array }.

POST /flows/{flowId}/restore

restore a flow.

Capability: flows.edit. Kind: write.

Field In Type Required
flowId path string yes
Idempotency-Key header string yes

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { id: string, name: string, enabled: boolean, version: integer, definition: { schemaVersion: 1, id: string, version: integer, name: string, trigger: object, entry: string, steps: object }, createdBy: string, runAs: string, trashedAt: string or null, createdAt: string }.

POST /flows/{flowId}/runs/clear

Clear terminal run history. Active runs remain.

Capability: flows.edit. Kind: write.

Field In Type Required
flowId path string yes
Idempotency-Key header string yes

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { ok: true }.

GET /flow-runs/{runId}

Get a run and its redacted step trace.

Capability: flows.edit. Kind: read.

Field In Type Required
runId path string yes

Output: { run: { id: string, flowId: string, version: integer, runAs: string, status: “queued” / “running” / “succeeded” / “failed” / “skipped” / “cancelled”, triggerKind: string, createdAt: number, startedAt: number or null, finishedAt: number or null, error: string or null, counted: boolean }, steps: array }.

GET /flows/{flowId}/runs

Page through newest flow runs.

Capability: flows.edit. Kind: read.

Field In Type Required
flowId path string yes
status query “queued” / “running” / “succeeded” / “failed” / “skipped” / “cancelled” no
cursor query string no
limit query integer no

Output: { items: array, nextCursor: string or null }.

POST /flows/secrets/delete

Delete a vault secret (owners/admins).

Capability: flows.edit. Kind: write.

Field In Type Required
Idempotency-Key header string yes
name body string yes

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { ok: true }.

GET /flows/secrets

List vault secret names for HTTP steps. Values are never returned.

Capability: flows.edit. Kind: read.

No input fields.

Output: { items: array }.

POST /flows/secrets

Create or replace a vault secret (owners/admins). HTTP steps reference it as {{secret.NAME}} and may only send it to the listed https origins.

Capability: flows.edit. Kind: write.

Field In Type Required
Idempotency-Key header string yes
name body string yes
origins body array yes
value body string yes

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { ok: true }.

POST /flows/test

Simulate a definition without writes or run usage.

Capability: flows.edit. Kind: read.

Field In Type Required
definition body { schemaVersion: 1, id: string, version: integer, name: string, trigger: { type: “record”, event: “created” / “updated” / “matching”, tableId: string, filter?: object, fieldId?: string, from?: object, to?: object } or { type: “track”, clientId?: string, projectId?: string } or { type: “schedule”, cron: string, timeZone: string, hungarianHolidays?: “include” / “skip-non-working-days” } or { type: “webhook”, method: “GET” / “POST” / “PUT” / “PATCH” / “DELETE”, payloadSchema: object } or { type: “inbound-email”, connectionId?: string } or { type: “form-submitted”, formId: string } or { type: “manual” } or { type: “flow”, flowId: string }, entry: string, steps: object } yes
sample body null or boolean or number or string or array<null or boolean or number or string or array or object> or object yes

Output: { status: string, steps: array }.

POST /flows/{flowId}/trash

trash a flow.

Capability: flows.edit. Kind: write.

Field In Type Required
flowId path string yes
Idempotency-Key header string yes

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { id: string, name: string, enabled: boolean, version: integer, definition: { schemaVersion: 1, id: string, version: integer, name: string, trigger: object, entry: string, steps: object }, createdBy: string, runAs: string, trashedAt: string or null, createdAt: string }.

PATCH /flows/{flowId}

Save a new immutable flow version.

Capability: flows.edit. Kind: write.

Field In Type Required
flowId path string yes
Idempotency-Key header string yes
baseVersion body integer yes
definition body { schemaVersion: 1, id: string, version: integer, name: string, trigger: { type: “record”, event: “created” / “updated” / “matching”, tableId: string, filter?: object, fieldId?: string, from?: object, to?: object } or { type: “track”, clientId?: string, projectId?: string } or { type: “schedule”, cron: string, timeZone: string, hungarianHolidays?: “include” / “skip-non-working-days” } or { type: “webhook”, method: “GET” / “POST” / “PUT” / “PATCH” / “DELETE”, payloadSchema: object } or { type: “inbound-email”, connectionId?: string } or { type: “form-submitted”, formId: string } or { type: “manual” } or { type: “flow”, flowId: string }, entry: string, steps: object } yes
runAs body string no

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { id: string, name: string, enabled: boolean, version: integer, definition: { schemaVersion: 1, id: string, version: integer, name: string, trigger: object, entry: string, steps: object }, createdBy: string, runAs: string, trashedAt: string or null, createdAt: string }.

GET /flows/usage

Get this workspace’s monthly run pool.

Capability: flows.edit. Kind: read.

No input fields.

Output: { used: number, included: number, plan: string, resetsOn: string, timeZone?: string }.

GET /flows/{flowId}/versions

List immutable flow versions.

Capability: flows.edit. Kind: read.

Field In Type Required
flowId path string yes

Output: { items: array }.

POST /flows/{flowId}/webhook/create

create an inbound webhook. Modes: srvo (signed + secret header), github (X-Hub-Signature-256), linear (Linear-Signature, paste Linear’s secret), path (secret token in the URL). Secrets are shown once.

Capability: flows.edit. Kind: write.

Field In Type Required
flowId path string yes
Idempotency-Key header string yes
mode body “srvo” / “github” / “linear” / “path” no
signingSecret body string no

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { publicId?: string, secret?: string, mode?: “srvo” / “github” / “linear” / “path”, ok: true }.

POST /flows/{flowId}/webhook/disable

disable an inbound webhook.

Capability: flows.edit. Kind: write.

Field In Type Required
flowId path string yes
Idempotency-Key header string yes

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { publicId?: string, secret?: string, mode?: “srvo” / “github” / “linear” / “path”, ok: true }.

POST /flows/{flowId}/webhook/rotate

rotate an inbound webhook. Modes: srvo (signed + secret header), github (X-Hub-Signature-256), linear (Linear-Signature, paste Linear’s secret), path (secret token in the URL). Secrets are shown once.

Capability: flows.edit. Kind: write.

Field In Type Required
flowId path string yes
Idempotency-Key header string yes
mode body “srvo” / “github” / “linear” / “path” no
signingSecret body string no

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { publicId?: string, secret?: string, mode?: “srvo” / “github” / “linear” / “path”, ok: true }.

import

POST /imports/connections/{connectionId}/disconnect

Disconnect your source connection and cancel its active runs.

Capability: import.plans.apply. Kind: write.

Field In Type Required
connectionId path string yes

Output: { disconnected: boolean }.

POST /imports/connections/{connectionId}/import

Start an import using your existing source connection.

Capability: import.plans.apply. Kind: write.

Field In Type Required
connectionId path string yes

Output: { run: { id: string, provider: “airtable” / “toggl” / “toggl-focus”, protocol?: “mcp”, stayConnected?: boolean, status: “discovering” / “picking” / “extracting” / “ready” / “applying” / “complete” / “cancelled” / “failed” / “partial”, version: integer, timeZone: string, selection: object or null, items?: array, spaceId: string or null, target?: object, destinationRevision?: string, mappings: object or null, progress: object, importJobId: string or null, error: string or null, errorDetail?: object, wakeAt: integer, createdAt: integer, updatedAt: integer, connected: boolean } }.

GET /imports/connections

List your source connections without credentials.

Capability: import.plans.apply. Kind: read.

No input fields.

Output: { connections: array }.

POST /imports/connector/{runId}/cancel

Stop an own import run and delete its token. Committed rows stay.

Capability: import.plans.apply. Kind: write.

Field In Type Required
runId path string yes
baseVersion body integer yes

Output: { run: { id: string, provider: “airtable” / “toggl” / “toggl-focus”, protocol?: “mcp”, stayConnected?: boolean, status: “discovering” / “picking” / “extracting” / “ready” / “applying” / “complete” / “cancelled” / “failed” / “partial”, version: integer, timeZone: string, selection: object or null, items?: array, spaceId: string or null, target?: object, destinationRevision?: string, mappings: object or null, progress: object, importJobId: string or null, error: string or null, errorDetail?: object, wakeAt: integer, createdAt: integer, updatedAt: integer, connected: boolean } }.

POST /imports/connector

Connect Airtable or Toggl with a personal token for one import.

Capability: import.plans.apply. Kind: write.

Field In Type Required
provider body “airtable” / “toggl” / “toggl-focus” yes
timeZone body string yes
token body string yes

Output: { run: { id: string, provider: “airtable” / “toggl” / “toggl-focus”, protocol?: “mcp”, stayConnected?: boolean, status: “discovering” / “picking” / “extracting” / “ready” / “applying” / “complete” / “cancelled” / “failed” / “partial”, version: integer, timeZone: string, selection: object or null, items?: array, spaceId: string or null, target?: object, destinationRevision?: string, mappings: object or null, progress: object, importJobId: string or null, error: string or null, errorDetail?: object, wakeAt: integer, createdAt: integer, updatedAt: integer, connected: boolean } }.

GET /imports/connector/{runId}

Get an own import run, its discovery while picking and its plan while ready.

Capability: import.jobs.read. Kind: read.

Field In Type Required
runId path string yes
itemId query string no

Output: { run: { id: string, provider: “airtable” / “toggl” / “toggl-focus”, protocol?: “mcp”, stayConnected?: boolean, status: “discovering” / “picking” / “extracting” / “ready” / “applying” / “complete” / “cancelled” / “failed” / “partial”, version: integer, timeZone: string, selection: object or null, items?: array, spaceId: string or null, target?: object, destinationRevision?: string, mappings: object or null, progress: object, importJobId: string or null, error: string or null, errorDetail?: object, wakeAt: integer, createdAt: integer, updatedAt: integer, connected: boolean }, discovery?: unknown, plan?: { version: 1, source: “airtable” / “csv” / “nocodb” / “monday” / “notion” / “trello” / “asana” / “clickup” / “linear”, sourceId: string, pages?: array, timeTags?: array, timeEntries?: array, tables: array, fields: array, records: array, links: array, fileReferences: array, people: array, warnings: array, unsupported: array, views: array, summary: object } or { source: “airtable” / “csv” / “nocodb” / “monday” / “notion” / “trello” / “asana” / “clickup” / “linear”, sourceId: string, pages?: array, timeTags?: array, tables: array, fields: array, links: array, fileReferences: array, people: array, warnings: array, unsupported: array, views: array, summary: object, planVersion: 2, timeEntryBlock?: object, recordBlocks: array } }.

POST /imports/connector/{runId}/pick

Choose what to import and where, then fetch it in the background.

Capability: import.plans.apply. Kind: write.

Field In Type Required
runId path string yes
baseVersion body integer yes
selection body { provider: “airtable”, baseId?: string, bases?: array, tableIds?: array } or { provider: “toggl” / “toggl-focus”, organizationId?: integer, workspaceId: integer, kinds: { clients: boolean, projects: boolean, tags: boolean, entries: boolean }, startDate?: string, endDate?: string } yes
spaceId body string no
target body { kind: “existing”, spaceId: string } or { kind: “section”, audience?: “private” / “workspace”, name?: string } or { kind: “folder”, folderId: string, name?: string } or { kind: “new”, teamId: string, name: string } no

Output: { run: { id: string, provider: “airtable” / “toggl” / “toggl-focus”, protocol?: “mcp”, stayConnected?: boolean, status: “discovering” / “picking” / “extracting” / “ready” / “applying” / “complete” / “cancelled” / “failed” / “partial”, version: integer, timeZone: string, selection: object or null, items?: array, spaceId: string or null, target?: object, destinationRevision?: string, mappings: object or null, progress: object, importJobId: string or null, error: string or null, errorDetail?: object, wakeAt: integer, createdAt: integer, updatedAt: integer, connected: boolean } }.

POST /imports/connector/{runId}/retry

Retry one failed table without repeating completed tables.

Capability: import.plans.apply. Kind: write.

Field In Type Required
runId path string yes
baseVersion body integer yes
itemId body string yes

Output: { run: { id: string, provider: “airtable” / “toggl” / “toggl-focus”, protocol?: “mcp”, stayConnected?: boolean, status: “discovering” / “picking” / “extracting” / “ready” / “applying” / “complete” / “cancelled” / “failed” / “partial”, version: integer, timeZone: string, selection: object or null, items?: array, spaceId: string or null, target?: object, destinationRevision?: string, mappings: object or null, progress: object, importJobId: string or null, error: string or null, errorDetail?: object, wakeAt: integer, createdAt: integer, updatedAt: integer, connected: boolean } }.

POST /imports/connector/{runId}/start

Apply the previewed plan in the background with the reviewed mappings.

Capability: import.plans.apply. Kind: write.

Field In Type Required
runId path string yes
baseVersion body integer yes
mappings body { tableMappings?: object, fieldMappings?: object } yes

Output: { run: { id: string, provider: “airtable” / “toggl” / “toggl-focus”, protocol?: “mcp”, stayConnected?: boolean, status: “discovering” / “picking” / “extracting” / “ready” / “applying” / “complete” / “cancelled” / “failed” / “partial”, version: integer, timeZone: string, selection: object or null, items?: array, spaceId: string or null, target?: object, destinationRevision?: string, mappings: object or null, progress: object, importJobId: string or null, error: string or null, errorDetail?: object, wakeAt: integer, createdAt: integer, updatedAt: integer, connected: boolean } }.

POST /imports/files/preview

Preview base64 export files before importing: up to 50 files, 5 MB total and 50,000 rows. Writes no destination data.

Capability: import.plans.apply. Kind: read.

Field In Type Required
columns body object no
files body array<{ name: string, base64: string }> yes
idColumn body string no
sheet body string no
source body “csv” / “xlsx” / “monday” / “nocodb” / “airtable” / “toggl” / “notion” / “trello” / “asana” / “clickup” / “linear” yes
sourceId body string yes
spaceId body string no
target body { kind: “existing”, spaceId: string } or { kind: “section”, audience?: “private” / “workspace”, name?: string } or { kind: “folder”, folderId: string, name?: string } or { kind: “new”, teamId: string, name: string } no
timeZone body string no

Output: { plan: { version: 1, source: “airtable” / “csv” / “nocodb” / “monday” / “notion” / “trello” / “asana” / “clickup” / “linear”, sourceId: string, pages?: array, timeTags?: array, timeEntries?: array, tables: array, fields: array, records: array, links: array, fileReferences: array, people: array, warnings: array, unsupported: array, views: array, summary: object } or { source: “airtable” / “csv” / “nocodb” / “monday” / “notion” / “trello” / “asana” / “clickup” / “linear”, sourceId: string, pages?: array, timeTags?: array, tables: array, fields: array, links: array, fileReferences: array, people: array, warnings: array, unsupported: array, views: array, summary: object, planVersion: 2, timeEntryBlock?: object, recordBlocks: array }, sheets?: array }.

POST /imports/jobs/{jobId}/cancel

Stop an owned import after its last committed batch. Keep imported data.

Capability: import.plans.apply. Kind: write.

Field In Type Required
jobId path string yes
baseVersion body integer yes

Output: { job: { id: string, spaceId: string, folderId?: string, notesFolderId?: string, planHash: string, status: “running” / “complete” / “rolling_back” / “rolled_back”, cancelled: boolean, hasTrack: boolean, issues: array, cursor: integer, total: integer, version: integer, resumeToken: string or null, createdSpace: boolean, updatedAt: string } }.

GET /imports/jobs/{jobId}

Get an import job and its committed progress.

Capability: import.jobs.read. Kind: read.

Field In Type Required
jobId path string yes

Output: { job: { id: string, spaceId: string, folderId?: string, notesFolderId?: string, planHash: string, status: “running” / “complete” / “rolling_back” / “rolled_back”, cancelled: boolean, hasTrack: boolean, issues: array, cursor: integer, total: integer, version: integer, resumeToken: string or null, createdSpace: boolean, updatedAt: string } }.

POST /imports/jobs/{jobId}/rollback

Trash objects created by an import, in resumable batches.

Capability: import.jobs.rollback. Kind: destructive.

Field In Type Required
jobId path string yes
Srvo-Confirmation header string no

Srvo-Confirmation: Without it the call returns a preview and a token; send the token back to commit.

Output: { job: { id: string, spaceId: string, folderId?: string, notesFolderId?: string, planHash: string, status: “running” / “complete” / “rolling_back” / “rolled_back”, cancelled: boolean, hasTrack: boolean, issues: array, cursor: integer, total: integer, version: integer, resumeToken: string or null, createdSpace: boolean, updatedAt: string } } or { preview: { summary: string, counts: object, warnings: array }, confirmationToken: string, expiresAt: string }.

POST /imports/apply

Preview and apply a reviewed import plan in resumable batches.

Capability: import.plans.apply. Kind: destructive.

Field In Type Required
Srvo-Confirmation header string no
jobId body string no
options body { conflictPolicy?: “source_wins”, batchSize?: integer, tableMappings?: object, fieldMappings?: object } no
plan body { version: 1, source: “airtable” / “csv” / “nocodb” / “monday” / “notion” / “trello” / “asana” / “clickup” / “linear”, sourceId: string, pages?: array, timeTags?: array, timeEntries?: array, tables: array, fields: array, records: array, links: array, fileReferences: array, people: array, warnings: array, unsupported: array, views: array, summary: { tables: array, totals: object, conversions: array, lossyConversions: integer, warnings: integer, unsupported: integer } } or { source: “airtable” / “csv” / “nocodb” / “monday” / “notion” / “trello” / “asana” / “clickup” / “linear”, sourceId: string, pages?: array, timeTags?: array, tables: array, fields: array, links: array, fileReferences: array, people: array, warnings: array, unsupported: array, views: array, summary: { tables: array, totals: object, conversions: array, lossyConversions: integer, warnings: integer, unsupported: integer }, planVersion: 2, timeEntryBlock?: { rows: array<array>, dictionaries?: object, prefixes?: object }, recordBlocks: array } no
requestId body string no
resumeToken body string no
target body { kind: “existing”, spaceId: string } or { kind: “section”, audience?: “private” / “workspace”, name?: string } or { kind: “folder”, folderId: string, name?: string } or { kind: “new”, teamId: string, name: string } no

Srvo-Confirmation: Without it the call returns a preview and a token; send the token back to commit.

Output: { job: { id: string, spaceId: string, folderId?: string, notesFolderId?: string, planHash: string, status: “running” / “complete” / “rolling_back” / “rolled_back”, cancelled: boolean, hasTrack: boolean, issues: array, cursor: integer, total: integer, version: integer, resumeToken: string or null, createdSpace: boolean, updatedAt: string } } or { preview: { summary: string, counts: object, warnings: array }, confirmationToken: string, expiresAt: string }.

metrics

POST /metrics/series

Query readable metric series and previous periods with the SRVO Script contract.

Capability: boards.records.read. Kind: read.

Field In Type Required
compareTo body “previousPeriod” no
filters body array<{ field: string, op: “eq” / “neq”, value: string or number or boolean } or { field: string, op: “in”, values: array } or { field: string, op: “gt” / “gte” / “lt” / “lte”, value: number or string } or { field: string, op: “isEmpty” / “isNotEmpty” }> no
groupBy body array<string or “date:day” / “date:week” / “date:month”> no
metrics body array<string or { tableId: string, op: “sum” / “avg” / “min” / “max” / “countRows” / “countNonNull” / “percent”, field?: string, dateField?: string }> yes
range body { preset: “thisWeek” / “lastWeek” / “thisMonth” / “lastMonth” } or { lastDays: integer } or { from: string, to: string } no

Output: { status: “complete” / “partial” / “stale” / “restricted”, series: array, totals: array, previousTotals: array or null, unit: string or null, range: { startInclusive: string, endExclusive: string } or null, watermark: string or null, warnings: array }.

POST /metrics/check

Validate metric tables, fields, units, ranges and access without aggregating.

Capability: boards.records.read. Kind: read.

Field In Type Required
compareTo body “previousPeriod” no
filters body array<{ field: string, op: “eq” / “neq”, value: string or number or boolean } or { field: string, op: “in”, values: array } or { field: string, op: “gt” / “gte” / “lt” / “lte”, value: number or string } or { field: string, op: “isEmpty” / “isNotEmpty” }> no
groupBy body array<string or “date:day” / “date:week” / “date:month”> no
metrics body array<string or { tableId: string, op: “sum” / “avg” / “min” / “max” / “countRows” / “countNonNull” / “percent”, field?: string, dateField?: string }> yes
range body { preset: “thisWeek” / “lastWeek” / “thisMonth” / “lastMonth” } or { lastDays: integer } or { from: string, to: string } no

Output: { ok: boolean, restricted: boolean, issues: array }.

notes

POST /notes/{pageId}/paragraphs

Append one plain-text paragraph (max 50,000 characters) to the end of a Notes page. Pass the page’s current bodyVersion as baseVersion from getNote; a stale version fails with CONFLICT. Returns the updated page.

Capability: notes.pages.edit. Kind: write.

Field In Type Required
pageId path string yes
baseVersion body integer yes
text body string yes

Output: { page: { id: string, spaceId: string, parentId: string or null, title: string, icon: string or null, rank: string, visibility: “inherit” / “private”, createdBy: string or null, createdAt: string, updatedBy: string or null, updatedAt: string, deletedAt: string or null, version: integer, bodyVersion: integer, blocks: array, quick: boolean, canEdit: boolean }, changeId?: integer }.

POST /notes

Create a Notes page in a space (or under parentId), or a private quick note. Returns the new page. Send an idempotencyKey to make retries safe.

Capability: notes.pages.edit. Kind: write.

Field In Type Required
Idempotency-Key header string yes
blocks body array<{ id: string, type: “heading”, level: 1 or 2 or 3, text: array } or { id: string, type: “paragraph”, text: array } or { id: string, type: “bullet”, text: array, indent: integer } or { id: string, type: “numbered”, text: array, indent: integer } or { id: string, type: “todo”, text: array, checked: boolean } or { id: string, type: “callout”, icon: string, tone: “gray” / “red” / “orange” / “amber” / “yellow” / “green” / “teal” / “cyan” / “sky” / “blue” / “indigo” / “purple” / “pink”, text: array } or { id: string, type: “quote”, text: array } or { id: string, type: “code”, lang: string, code: string } or { id: string, type: “divider” } or { id: string, type: “embed_view”, viewId: string } or { id: string, type: “file”, fileId: string } or { id: string, type: “action_item”, text: array, assigneeId: string or null, due: string or null, recordId: string or null }> no
icon body string or null no
id body string no
parentId body string or null no
private body boolean no
quick body boolean no
spaceId body string yes
title body string yes

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { page: { id: string, spaceId: string, parentId: string or null, title: string, icon: string or null, rank: string, visibility: “inherit” / “private”, createdBy: string or null, createdAt: string, updatedBy: string or null, updatedAt: string, deletedAt: string or null, version: integer, bodyVersion: integer, blocks: array, quick: boolean, canEdit: boolean }, changeId?: integer }.

GET /notes/{noteId}/export

Export noteId as safe Markdown. Returns filename, contentType and base64 body over MCP, up to 1 MiB; use REST for larger files.

Capability: notes.pages.read. Kind: read.

Field In Type Required
noteId path string yes

Output: string.

GET /notes/{noteId}

Read a Notes page and its validated document blocks.

Capability: notes.pages.read. Kind: read.

Field In Type Required
noteId path string yes

Output: { page?: { id: string, spaceId: string, parentId: string or null, title: string, icon: string or null, rank: string, visibility: “inherit” / “private”, createdBy: string or null, createdAt: string, updatedBy: string or null, updatedAt: string, deletedAt: string or null, version: integer, bodyVersion: integer, blocks: array, quick: boolean, canEdit: boolean }, note: { id: string, spaceId: string, title: string, markdown: string, updatedAt: string } }.

GET /notes

List visible pages in a space or this member’s quick notes inbox.

Capability: notes.pages.read. Kind: read.

Field In Type Required
spaceId query string no
quick query “true” / “false” no
after query string no
limit query integer no

Output: { pages: array, nextCursor: string or null }.

POST /notes/{pageId}/move

Move a Notes page and its subpages to another space or parent page. Pass the page’s version as baseVersion. Returns the moved page.

Capability: notes.pages.edit. Kind: write.

Field In Type Required
pageId path string yes
baseVersion body integer yes
parentId body string or null yes
spaceId body string yes

Output: { page: { id: string, spaceId: string, parentId: string or null, title: string, icon: string or null, rank: string, visibility: “inherit” / “private”, createdBy: string or null, createdAt: string, updatedBy: string or null, updatedAt: string, deletedAt: string or null, version: integer, bodyVersion: integer, blocks: array, quick: boolean, canEdit: boolean }, changeId?: integer }.

PATCH /notes/{pageId}

Rename a Notes page. Pass the page’s version as baseVersion; a stale version fails with CONFLICT.

Capability: notes.pages.edit. Kind: write.

Field In Type Required
pageId path string yes
baseVersion body integer yes
title body string yes

Output: { page: { id: string, spaceId: string, parentId: string or null, title: string, icon: string or null, rank: string, visibility: “inherit” / “private”, createdBy: string or null, createdAt: string, updatedBy: string or null, updatedAt: string, deletedAt: string or null, version: integer, bodyVersion: integer, blocks: array, quick: boolean, canEdit: boolean }, changeId?: integer }.

POST /notes/{pageId}/restore

Restore a trashed Notes page and its subpages. Call without confirmationToken to preview, then again with the returned token to commit.

Capability: notes.pages.edit. Kind: destructive.

Field In Type Required
pageId path string yes
Srvo-Confirmation header string no
baseVersion body integer yes

Srvo-Confirmation: Without it the call returns a preview and a token; send the token back to commit.

Output: { page: { id: string, spaceId: string, parentId: string or null, title: string, icon: string or null, rank: string, visibility: “inherit” / “private”, createdBy: string or null, createdAt: string, updatedBy: string or null, updatedAt: string, deletedAt: string or null, version: integer, bodyVersion: integer, blocks: array, quick: boolean, canEdit: boolean }, changeId?: integer } or { preview: { summary: string, counts: object, warnings: array }, confirmationToken: string, expiresAt: string }.

PUT /notes/{pageId}/body

Replace a Notes page body with the given blocks. Pass the page’s bodyVersion as baseVersion; a stale version fails with CONFLICT. Earlier bodies stay restorable from listNoteVersions. Prefer appendNoteParagraph for small additions.

Capability: notes.pages.edit. Kind: write.

Field In Type Required
pageId path string yes
baseVersion body integer yes
blocks body array<{ id: string, type: “heading”, level: 1 or 2 or 3, text: array } or { id: string, type: “paragraph”, text: array } or { id: string, type: “bullet”, text: array, indent: integer } or { id: string, type: “numbered”, text: array, indent: integer } or { id: string, type: “todo”, text: array, checked: boolean } or { id: string, type: “callout”, icon: string, tone: “gray” / “red” / “orange” / “amber” / “yellow” / “green” / “teal” / “cyan” / “sky” / “blue” / “indigo” / “purple” / “pink”, text: array } or { id: string, type: “quote”, text: array } or { id: string, type: “code”, lang: string, code: string } or { id: string, type: “divider” } or { id: string, type: “embed_view”, viewId: string } or { id: string, type: “file”, fileId: string } or { id: string, type: “action_item”, text: array, assigneeId: string or null, due: string or null, recordId: string or null }> yes

Output: { page: { id: string, spaceId: string, parentId: string or null, title: string, icon: string or null, rank: string, visibility: “inherit” / “private”, createdBy: string or null, createdAt: string, updatedBy: string or null, updatedAt: string, deletedAt: string or null, version: integer, bodyVersion: integer, blocks: array, quick: boolean, canEdit: boolean }, changeId?: integer }.

POST /notes/{pageId}/trash

Move a Notes page and its subpages to trash. Call without confirmationToken to preview, then again with the returned token to commit.

Capability: notes.pages.edit. Kind: destructive.

Field In Type Required
pageId path string yes
Srvo-Confirmation header string no
baseVersion body integer yes

Srvo-Confirmation: Without it the call returns a preview and a token; send the token back to commit.

Output: { page: { id: string, spaceId: string, parentId: string or null, title: string, icon: string or null, rank: string, visibility: “inherit” / “private”, createdBy: string or null, createdAt: string, updatedBy: string or null, updatedAt: string, deletedAt: string or null, version: integer, bodyVersion: integer, blocks: array, quick: boolean, canEdit: boolean }, changeId?: integer } or { preview: { summary: string, counts: object, warnings: array }, confirmationToken: string, expiresAt: string }.

GET /notes/{pageId}/versions/{versionId}

Read one retained version of a visible Notes page.

Capability: notes.pages.read. Kind: read.

Field In Type Required
pageId path string yes
versionId path string yes

Output: { version: { id: string, at: string, authorId: string or null, kind: “auto” / “restore”, bodyVersion: integer }, blocks: array }.

GET /notes/{pageId}/versions

List the retained version metadata of a visible Notes page.

Capability: notes.pages.read. Kind: read.

Field In Type Required
pageId path string yes

Output: { versions: array }.

POST /notes/{pageId}/versions/{versionId}/restore

Restore a retained snapshot as a new version, preserving the previous body.

Capability: notes.pages.edit. Kind: write.

Field In Type Required
pageId path string yes
versionId path string yes
baseVersion body integer yes

Output: { page: { id: string, spaceId: string, parentId: string or null, title: string, icon: string or null, rank: string, visibility: “inherit” / “private”, createdBy: string or null, createdAt: string, updatedBy: string or null, updatedAt: string, deletedAt: string or null, version: integer, bodyVersion: integer, blocks: array, quick: boolean, canEdit: boolean }, changeId?: integer }.

send

POST /send/domains

Add a sending domain. Returns the DNS records to add; a background job checks them.

Capability: send.domains.manage. Kind: write.

Field In Type Required
clickTracking body boolean no
customReturnPath body string no
domain body string yes
openTracking body boolean no
region body “eu-central-1” / “eu-west-1” no
tls body “opportunistic” no

Output: { id: string, domain: string, status: “not_started” / “pending” / “partially_verified” / “verified” / “failed” / “temporary_failure”, records: array, region: “eu-central-1”, settings: { openTracking: boolean, clickTracking: boolean, tls: “opportunistic”, customReturnPath: string or null }, statusReason: string or null, createdAt: string, checkedAt: string or null, verifiedAt: string or null }.

DELETE /send/domains/{domainId}

Remove a sending domain. Its provider identity and DKIM keys are removed in the background.

Capability: send.domains.manage. Kind: write.

Field In Type Required
domainId path string yes

Output: { id: string, deleted: true }.

GET /send/domains/{domainId}

Read one sending domain with its DNS records and check status.

Capability: send.domains.manage. Kind: read.

Field In Type Required
domainId path string yes

Output: { id: string, domain: string, status: “not_started” / “pending” / “partially_verified” / “verified” / “failed” / “temporary_failure”, records: array, region: “eu-central-1”, settings: { openTracking: boolean, clickTracking: boolean, tls: “opportunistic”, customReturnPath: string or null }, statusReason: string or null, createdAt: string, checkedAt: string or null, verifiedAt: string or null }.

GET /send/domains

List sending domains with the DNS records to add and their check status.

Capability: send.domains.manage. Kind: read.

Field In Type Required
limit query integer no
after query string no
before query string no

Output: { domains: array, hasMore: boolean }.

PATCH /send/domains/{domainId}

Change a sending domain’s open/click tracking or TLS setting.

Capability: send.domains.manage. Kind: write.

Field In Type Required
domainId path string yes
clickTracking body boolean no
openTracking body boolean no
tls body “opportunistic” no

Output: { id: string, domain: string, status: “not_started” / “pending” / “partially_verified” / “verified” / “failed” / “temporary_failure”, records: array, region: “eu-central-1”, settings: { openTracking: boolean, clickTracking: boolean, tls: “opportunistic”, customReturnPath: string or null }, statusReason: string or null, createdAt: string, checkedAt: string or null, verifiedAt: string or null }.

POST /send/domains/{domainId}/verify

Ask for a fresh DNS check of a sending domain (runs within a minute).

Capability: send.domains.manage. Kind: write.

Field In Type Required
domainId path string yes

Output: { id: string, domain: string, status: “not_started” / “pending” / “partially_verified” / “verified” / “failed” / “temporary_failure”, records: array, region: “eu-central-1”, settings: { openTracking: boolean, clickTracking: boolean, tls: “opportunistic”, customReturnPath: string or null }, statusReason: string or null, createdAt: string, checkedAt: string or null, verifiedAt: string or null }.

POST /send/emails/batch

Send up to 100 emails at once (no attachments or scheduling). Strict: all or nothing; permissive: valid ones go out.

Capability: send.emails.send. Kind: write.

Field In Type Required
Idempotency-Key header string no
emails body array<{ from: string, to: string or array, cc?: string or array, bcc?: string or array, replyTo?: string or array, subject: string, html?: string, text?: string, headers?: object, tags?: array }> yes
validation body “strict” / “permissive” no

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { data: array, errors?: array }.

POST /send/emails/{emailId}/cancel

Cancel a scheduled email before it goes out.

Capability: send.emails.send. Kind: write.

Field In Type Required
emailId path string yes

Output: { id: string }.

GET /send/emails/{emailId}

Read one email sent through the API: recipients, subject, last event, and the body while kept.

Capability: send.messages.read. Kind: read.

Field In Type Required
emailId path string yes

Output: { id: string, from: string, to: array, cc: array, bcc: array, replyTo: array, subject: string, lastEvent: “queued” / “scheduled” / “sent” / “delivered” / “bounced” / “complained” / “canceled” / “failed” / “suppressed”, createdAt: string, scheduledAt: string or null, html: string or null, text: string or null, tags: array }.

GET /send/emails

List emails sent through the API or SMTP, newest first (system mail is never listed).

Capability: send.messages.read. Kind: read.

Field In Type Required
limit query integer no
after query string no
before query string no

Output: { items: array, hasMore: boolean }.

PATCH /send/emails/{emailId}

Move a scheduled email to another time (at most 30 days ahead). Only while it is scheduled.

Capability: send.emails.send. Kind: write.

Field In Type Required
emailId path string yes
scheduledAt body string yes

Output: { id: string }.

POST /send/emails

Send an email from a verified domain of this workspace (to, cc, bcc ≤ 50, attachments, optional scheduled_at).

Capability: send.emails.send. Kind: write.

Field In Type Required
Idempotency-Key header string no
attachments body array<{ content?: string, path?: string, filename?: string, contentType?: string, contentId?: string }> no
bcc body string or array no
cc body string or array no
from body string yes
headers body object no
html body string no
replyTo body string or array no
scheduledAt body string no
subject body string yes
tags body array<{ name: string, value: string }> no
text body string no
to body string or array yes

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { id: string }.

POST /send/emails/raw

Send a ready MIME message (the SMTP relay uses this): envelope sender, recipients (≤ 50) and the message as base64. Its From must be on the sender’s verified domain.

Capability: send.emails.send. Kind: write.

Field In Type Required
Idempotency-Key header string no
from body string yes
raw body string yes
to body array yes

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { id: string }.

POST /send/keys

Create a Send API key. The token is returned once.

Capability: send.keys.manage. Kind: write.

Field In Type Required
domainIds body array no
name body string yes
permission body “full_access” / “sending_access” no

Output: { key: { id: string, name: string, prefix: string, permission: “full_access” / “sending_access”, domainIds: array, lastUsedAt: string or null, revokedAt: string or null, createdAt: string, createdBy: string, createdByName?: string }, token: string }.

GET /send/keys

List the workspace’s active Send API keys (metadata only, never the token).

Capability: send.keys.manage. Kind: read.

Field In Type Required
limit query integer no
after query string no
before query string no

Output: { items: array, hasMore: boolean }.

POST /send/keys/{keyId}/revoke

Revoke a Send API key. It stops working at once.

Capability: send.keys.manage. Kind: write.

Field In Type Required
keyId path string yes

Output: { id: string, name: string, prefix: string, permission: “full_access” / “sending_access”, domainIds: array, lastUsedAt: string or null, revokedAt: string or null, createdAt: string, createdBy: string, createdByName?: string }.

GET /send/messages

List outbound emails of this workspace, newest first, with delivery status.

Capability: send.messages.read. Kind: read.

Field In Type Required
status query “queued” / “sent” / “delivered” / “bounced” / “complained” / “failed” / “suppressed” / “blocked” / “scheduled” / “canceled” no
limit query integer no

Output: { messages: array }.

GET /send/status

Whether this server has an email provider set up (without one, mail waits in the queue).

Capability: send.messages.read. Kind: read.

No input fields.

Output: { configured: boolean, provider: string or null }.

POST /send/suppressions

Suppress an email address: mail from this workspace’s Send API skips it from now on.

Capability: send.suppressions.manage. Kind: write.

Field In Type Required
Idempotency-Key header string no
email body string yes
reason body “manual” / “unsubscribe” no

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { id: string, email: string, reason: “hard_bounce” / “soft_bounce” / “complaint” / “unsubscribe” / “manual”, source: “srvo” / “api”, createdAt: string }.

POST /send/suppressions/batch/add

Suppress up to 1,000 email addresses at once. Addresses already listed keep their entry.

Capability: send.suppressions.manage. Kind: write.

Field In Type Required
Idempotency-Key header string no
emails body array yes
reason body “manual” / “unsubscribe” no

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { data: array }.

POST /send/suppressions/batch/remove

Remove up to 1,000 email addresses from the suppression list at once.

Capability: send.suppressions.manage. Kind: write.

Field In Type Required
emails body array yes

Output: { removed: integer }.

GET /send/suppressions/{suppressionId}

Read one suppression entry by its id or by the email address.

Capability: send.messages.read. Kind: read.

Field In Type Required
suppressionId path string yes

Output: { id: string, email: string, reason: “hard_bounce” / “soft_bounce” / “complaint” / “unsubscribe” / “manual”, source: “srvo” / “api”, createdAt: string }.

GET /send/suppressions

List the workspace’s suppressed email addresses, newest first (bounces, complaints, manual).

Capability: send.messages.read. Kind: read.

Field In Type Required
limit query integer no
after query string no
before query string no

Output: { items: array, hasMore: boolean }.

DELETE /send/suppressions/{suppressionId}

Remove an address from the suppression list (by id or address). Mail may reach it again, bounces included.

Capability: send.suppressions.manage. Kind: write.

Field In Type Required
suppressionId path string yes

Output: { id: string, email: string, deleted: true }.

sergio

POST /sergio/conversations

Create a private Sergio conversation

Capability: ai.agent.use. Kind: write.

Field In Type Required
scope body { kind: “project” / “client”, id: string } no
title body string no

Output: { id: string, ownerMemberId: string, title: string, pinned: boolean, archived: boolean, scope: { kind: “project” / “client”, id: string } or null, memoryUse: boolean, memoryLearn: boolean, createdAt: string, updatedAt: string, lastMessageAt: string or null, version: integer }.

POST /sergio/conversations/{id}/delete

Update your private conversation: delete

Capability: ai.agent.use. Kind: write.

Field In Type Required
id path string yes
baseVersion body integer yes
forgetLearned body boolean no

Output: { id: string, version: integer }.

GET /sergio/conversations/{id}

Read your conversation and a page of messages

Capability: ai.agent.use. Kind: read.

Field In Type Required
id path string yes
cursor query string no
limit query integer no

Output: { conversation: { id: string, ownerMemberId: string, title: string, pinned: boolean, archived: boolean, scope: object or null, memoryUse: boolean, memoryLearn: boolean, createdAt: string, updatedAt: string, lastMessageAt: string or null, version: integer }, messages: array, nextCursor: string or null }.

POST /sergio/conversations/list

List your private Sergio conversations

Capability: ai.agent.use. Kind: read.

Field In Type Required
cursor body string no
limit body integer no
pinned body boolean no
query body string no
scope body { kind: “project” / “client”, id: string } no

Output: { items: array, nextCursor: string or null }.

POST /sergio/conversations/{id}/move

Update your private conversation: move

Capability: ai.agent.use. Kind: write.

Field In Type Required
id path string yes
baseVersion body integer yes
forgetLearned body boolean no
scope body { kind: “project” / “client”, id: string } or null yes

Output: { id: string, ownerMemberId: string, title: string, pinned: boolean, archived: boolean, scope: { kind: “project” / “client”, id: string } or null, memoryUse: boolean, memoryLearn: boolean, createdAt: string, updatedAt: string, lastMessageAt: string or null, version: integer }.

POST /sergio/conversations/{id}/pin

Update your private conversation: pin

Capability: ai.agent.use. Kind: write.

Field In Type Required
id path string yes
baseVersion body integer yes
pinned body boolean yes

Output: { id: string, ownerMemberId: string, title: string, pinned: boolean, archived: boolean, scope: { kind: “project” / “client”, id: string } or null, memoryUse: boolean, memoryLearn: boolean, createdAt: string, updatedAt: string, lastMessageAt: string or null, version: integer }.

POST /sergio/conversations/{id}/rename

Update your private conversation: rename

Capability: ai.agent.use. Kind: write.

Field In Type Required
id path string yes
baseVersion body integer yes
title body string yes

Output: { id: string, ownerMemberId: string, title: string, pinned: boolean, archived: boolean, scope: { kind: “project” / “client”, id: string } or null, memoryUse: boolean, memoryLearn: boolean, createdAt: string, updatedAt: string, lastMessageAt: string or null, version: integer }.

POST /sergio/conversations/{id}/setMemory

Update your private conversation: setMemory

Capability: ai.agent.use. Kind: write.

Field In Type Required
id path string yes
baseVersion body integer yes
learn body boolean no
use body boolean no

Output: { id: string, ownerMemberId: string, title: string, pinned: boolean, archived: boolean, scope: { kind: “project” / “client”, id: string } or null, memoryUse: boolean, memoryLearn: boolean, createdAt: string, updatedAt: string, lastMessageAt: string or null, version: integer }.

POST /sergio/conversations/{id}/unpin

Unpin your private Sergio conversation

Capability: ai.agent.use. Kind: write.

Field In Type Required
id path string yes
baseVersion body integer yes

Output: { id: string, ownerMemberId: string, title: string, pinned: boolean, archived: boolean, scope: { kind: “project” / “client”, id: string } or null, memoryUse: boolean, memoryLearn: boolean, createdAt: string, updatedAt: string, lastMessageAt: string or null, version: integer }.

POST /sergio/external/list

Owner-only external coding agent chat list

Capability: ai.agent.use. Kind: read.

Field In Type Required
cursor body string no
limit body integer no
pinned body boolean no
query body string no
scope body { kind: “project” / “client”, id: string } no

Output: { items: array, nextCursor: string or null }.

POST /sergio/external/poll

Owner-only external coding agent chat poll

Capability: ai.agent.use. Kind: read.

Field In Type Required
cursor body string no
id body string yes
limit body integer no

Output: { conversation: { id: string, ownerMemberId: string, title: string, pinned: boolean, archived: boolean, scope: object or null, memoryUse: boolean, memoryLearn: boolean, createdAt: string, updatedAt: string, lastMessageAt: string or null, version: integer }, messages: array, nextCursor: string or null }.

POST /sergio/external/post

Owner-only external coding agent chat post

Capability: ai.agent.use. Kind: write.

Field In Type Required
Idempotency-Key header string yes
id body string yes
text body string yes

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { id: string, conversationId: string, parentMessageId: string or null, role: “user” / “assistant”, parts: array, status: “streaming” / “done” / “stopped” / “error”, createdAt: string, creditsUsed: number, model: string or null }.

POST /sergio/external/read

Owner-only external coding agent chat read

Capability: ai.agent.use. Kind: read.

Field In Type Required
cursor body string no
id body string yes
limit body integer no

Output: { conversation: { id: string, ownerMemberId: string, title: string, pinned: boolean, archived: boolean, scope: object or null, memoryUse: boolean, memoryLearn: boolean, createdAt: string, updatedAt: string, lastMessageAt: string or null, version: integer }, messages: array, nextCursor: string or null }.

POST /sergio/memory/entries/copyToMine

Read or manage Sergio memory under scope and audience policy: entries.copyToMine

Capability: ai.agent.use. Kind: write.

Field In Type Required
Idempotency-Key header string yes
audience body “shared” / “member” no
baseVersion body integer no
confirmed body boolean no
conversationId body string no
cursor body string no
id body string no
instructions body string no
kind body “decision” / “fact” / “preference” / “open_item” no
limit body integer no
scope body { kind: “project” / “client”, id: string } no
sources body array<{ source: object, sourceVersion: integer }> no
summary body string no
summaryEntries body array<{ id: string, version: integer }> no
text body string no

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { id: string, memoryId: string, kind: “decision” / “fact” / “preference” / “open_item”, text: string, pinned: boolean, forgotten: boolean, shared: boolean, origin: “learned” / “user” / “promoted”, humanEdited: boolean, state: “active” / “stale” / “audience_narrowed” / “source_in_trash” / “closed”, badges: array<“new” / “pinned” / “stale”>, sources: array, createdBy: string, createdFor: string or null, asOf: string or null, createdAt: string, updatedAt: string, version: integer }.

POST /sergio/memory/entries/create

Read or manage Sergio memory under scope and audience policy: entries.create

Capability: ai.agent.use. Kind: write.

Field In Type Required
Idempotency-Key header string yes
audience body “shared” / “member” no
baseVersion body integer no
confirmed body boolean no
conversationId body string no
cursor body string no
id body string no
instructions body string no
kind body “decision” / “fact” / “preference” / “open_item” no
limit body integer no
scope body { kind: “project” / “client”, id: string } no
sources body array<{ source: object, sourceVersion: integer }> no
summary body string no
summaryEntries body array<{ id: string, version: integer }> no
text body string no

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { id: string, memoryId: string, kind: “decision” / “fact” / “preference” / “open_item”, text: string, pinned: boolean, forgotten: boolean, shared: boolean, origin: “learned” / “user” / “promoted”, humanEdited: boolean, state: “active” / “stale” / “audience_narrowed” / “source_in_trash” / “closed”, badges: array<“new” / “pinned” / “stale”>, sources: array, createdBy: string, createdFor: string or null, asOf: string or null, createdAt: string, updatedAt: string, version: integer }.

POST /sergio/memory/entries/forget

Read or manage Sergio memory under scope and audience policy: entries.forget

Capability: ai.agent.use. Kind: write.

Field In Type Required
Idempotency-Key header string yes
audience body “shared” / “member” no
baseVersion body integer no
confirmed body boolean no
conversationId body string no
cursor body string no
id body string no
instructions body string no
kind body “decision” / “fact” / “preference” / “open_item” no
limit body integer no
scope body { kind: “project” / “client”, id: string } no
sources body array<{ source: object, sourceVersion: integer }> no
summary body string no
summaryEntries body array<{ id: string, version: integer }> no
text body string no

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { id: string, version: integer }.

POST /sergio/memory/entries/list

Read or manage Sergio memory under scope and audience policy: entries.list

Capability: ai.agent.use. Kind: read.

Field In Type Required
audience body “shared” / “member” no
baseVersion body integer no
confirmed body boolean no
conversationId body string no
cursor body string no
id body string no
instructions body string no
kind body “decision” / “fact” / “preference” / “open_item” no
limit body integer no
scope body { kind: “project” / “client”, id: string } no
sources body array<{ source: object, sourceVersion: integer }> no
summary body string no
summaryEntries body array<{ id: string, version: integer }> no
text body string no

Output: { items: array, nextCursor: string or null }.

POST /sergio/memory/entries/pin

Read or manage Sergio memory under scope and audience policy: entries.pin

Capability: ai.agent.use. Kind: write.

Field In Type Required
Idempotency-Key header string yes
audience body “shared” / “member” no
baseVersion body integer no
confirmed body boolean no
conversationId body string no
cursor body string no
id body string no
instructions body string no
kind body “decision” / “fact” / “preference” / “open_item” no
limit body integer no
scope body { kind: “project” / “client”, id: string } no
sources body array<{ source: object, sourceVersion: integer }> no
summary body string no
summaryEntries body array<{ id: string, version: integer }> no
text body string no

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { id: string, memoryId: string, kind: “decision” / “fact” / “preference” / “open_item”, text: string, pinned: boolean, forgotten: boolean, shared: boolean, origin: “learned” / “user” / “promoted”, humanEdited: boolean, state: “active” / “stale” / “audience_narrowed” / “source_in_trash” / “closed”, badges: array<“new” / “pinned” / “stale”>, sources: array, createdBy: string, createdFor: string or null, asOf: string or null, createdAt: string, updatedAt: string, version: integer }.

POST /sergio/memory/entries/restore

Read or manage Sergio memory under scope and audience policy: entries.restore

Capability: ai.agent.use. Kind: write.

Field In Type Required
Idempotency-Key header string yes
audience body “shared” / “member” no
baseVersion body integer no
confirmed body boolean no
conversationId body string no
cursor body string no
id body string no
instructions body string no
kind body “decision” / “fact” / “preference” / “open_item” no
limit body integer no
scope body { kind: “project” / “client”, id: string } no
sources body array<{ source: object, sourceVersion: integer }> no
summary body string no
summaryEntries body array<{ id: string, version: integer }> no
text body string no

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { id: string, memoryId: string, kind: “decision” / “fact” / “preference” / “open_item”, text: string, pinned: boolean, forgotten: boolean, shared: boolean, origin: “learned” / “user” / “promoted”, humanEdited: boolean, state: “active” / “stale” / “audience_narrowed” / “source_in_trash” / “closed”, badges: array<“new” / “pinned” / “stale”>, sources: array, createdBy: string, createdFor: string or null, asOf: string or null, createdAt: string, updatedAt: string, version: integer }.

POST /sergio/memory/entries/share

Read or manage Sergio memory under scope and audience policy: entries.share

Capability: ai.agent.use. Kind: write.

Field In Type Required
Idempotency-Key header string yes
audience body “shared” / “member” no
baseVersion body integer no
confirmed body boolean no
conversationId body string no
cursor body string no
id body string no
instructions body string no
kind body “decision” / “fact” / “preference” / “open_item” no
limit body integer no
scope body { kind: “project” / “client”, id: string } no
sources body array<{ source: object, sourceVersion: integer }> no
summary body string no
summaryEntries body array<{ id: string, version: integer }> no
text body string no

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { text: string, audienceCount: integer, canShare: boolean, reason: “SOURCE_NOT_COMMON” or null, entry?: { id: string, memoryId: string, kind: “decision” / “fact” / “preference” / “open_item”, text: string, pinned: boolean, forgotten: boolean, shared: boolean, origin: “learned” / “user” / “promoted”, humanEdited: boolean, state: “active” / “stale” / “audience_narrowed” / “source_in_trash” / “closed”, badges: array<“new” / “pinned” / “stale”>, sources: array, createdBy: string, createdFor: string or null, asOf: string or null, createdAt: string, updatedAt: string, version: integer } }.

POST /sergio/memory/entries/unpin

Read or manage Sergio memory under scope and audience policy: entries.unpin

Capability: ai.agent.use. Kind: write.

Field In Type Required
Idempotency-Key header string yes
audience body “shared” / “member” no
baseVersion body integer no
confirmed body boolean no
conversationId body string no
cursor body string no
id body string no
instructions body string no
kind body “decision” / “fact” / “preference” / “open_item” no
limit body integer no
scope body { kind: “project” / “client”, id: string } no
sources body array<{ source: object, sourceVersion: integer }> no
summary body string no
summaryEntries body array<{ id: string, version: integer }> no
text body string no

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { id: string, memoryId: string, kind: “decision” / “fact” / “preference” / “open_item”, text: string, pinned: boolean, forgotten: boolean, shared: boolean, origin: “learned” / “user” / “promoted”, humanEdited: boolean, state: “active” / “stale” / “audience_narrowed” / “source_in_trash” / “closed”, badges: array<“new” / “pinned” / “stale”>, sources: array, createdBy: string, createdFor: string or null, asOf: string or null, createdAt: string, updatedAt: string, version: integer }.

POST /sergio/memory/entries/update

Read or manage Sergio memory under scope and audience policy: entries.update

Capability: ai.agent.use. Kind: write.

Field In Type Required
Idempotency-Key header string yes
audience body “shared” / “member” no
baseVersion body integer no
confirmed body boolean no
conversationId body string no
cursor body string no
id body string no
instructions body string no
kind body “decision” / “fact” / “preference” / “open_item” no
limit body integer no
scope body { kind: “project” / “client”, id: string } no
sources body array<{ source: object, sourceVersion: integer }> no
summary body string no
summaryEntries body array<{ id: string, version: integer }> no
text body string no

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { id: string, memoryId: string, kind: “decision” / “fact” / “preference” / “open_item”, text: string, pinned: boolean, forgotten: boolean, shared: boolean, origin: “learned” / “user” / “promoted”, humanEdited: boolean, state: “active” / “stale” / “audience_narrowed” / “source_in_trash” / “closed”, badges: array<“new” / “pinned” / “stale”>, sources: array, createdBy: string, createdFor: string or null, asOf: string or null, createdAt: string, updatedAt: string, version: integer }.

POST /sergio/memory/explain

Read or manage Sergio memory under scope and audience policy: explain

Capability: ai.agent.use. Kind: read.

Field In Type Required
audience body “shared” / “member” no
baseVersion body integer no
confirmed body boolean no
conversationId body string no
cursor body string no
id body string no
instructions body string no
kind body “decision” / “fact” / “preference” / “open_item” no
limit body integer no
scope body { kind: “project” / “client”, id: string } no
sources body array<{ source: object, sourceVersion: integer }> no
summary body string no
summaryEntries body array<{ id: string, version: integer }> no
text body string no

Output: { scope: { kind: “project” / “client”, id: string } or { kind: “workspace” }, parts: array, linkedItems: array, budget: { memory: integer, liveContext: integer, chat: integer, total: integer }, estimatedCredits: number, memoryUse: boolean, memoryLearn: boolean }.

POST /sergio/memory/get

Read or manage Sergio memory under scope and audience policy: get

Capability: ai.agent.use. Kind: read.

Field In Type Required
audience body “shared” / “member” no
baseVersion body integer no
confirmed body boolean no
conversationId body string no
cursor body string no
id body string no
instructions body string no
kind body “decision” / “fact” / “preference” / “open_item” no
limit body integer no
scope body { kind: “project” / “client”, id: string } no
sources body array<{ source: object, sourceVersion: integer }> no
summary body string no
summaryEntries body array<{ id: string, version: integer }> no
text body string no

Output: { id: string, scope: { kind: “project” / “client”, id: string } or { kind: “workspace” }, audience: “shared” / “member”, summary: string, instructions: string, editable: boolean, paused: boolean, counts: { decision: integer, fact: integer, preference: integer, open_item: integer }, updatedAt: string, updatedBy: string or null, version: integer } or null.

POST /sergio/memory/history/list

Read or manage Sergio memory under scope and audience policy: history.list

Capability: ai.agent.use. Kind: read.

Field In Type Required
audience body “shared” / “member” no
baseVersion body integer no
confirmed body boolean no
conversationId body string no
cursor body string no
id body string no
instructions body string no
kind body “decision” / “fact” / “preference” / “open_item” no
limit body integer no
scope body { kind: “project” / “client”, id: string } no
sources body array<{ source: object, sourceVersion: integer }> no
summary body string no
summaryEntries body array<{ id: string, version: integer }> no
text body string no

Output: { items: array, nextCursor: string or null }.

POST /sergio/memory/instructions/set

Read or manage Sergio memory under scope and audience policy: instructions.set

Capability: ai.agent.use. Kind: write.

Field In Type Required
Idempotency-Key header string yes
audience body “shared” / “member” no
baseVersion body integer no
confirmed body boolean no
conversationId body string no
cursor body string no
id body string no
instructions body string no
kind body “decision” / “fact” / “preference” / “open_item” no
limit body integer no
scope body { kind: “project” / “client”, id: string } no
sources body array<{ source: object, sourceVersion: integer }> no
summary body string no
summaryEntries body array<{ id: string, version: integer }> no
text body string no

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { id: string, scope: { kind: “project” / “client”, id: string } or { kind: “workspace” }, audience: “shared” / “member”, summary: string, instructions: string, editable: boolean, paused: boolean, counts: { decision: integer, fact: integer, preference: integer, open_item: integer }, updatedAt: string, updatedBy: string or null, version: integer }.

POST /sergio/memory/pause

Read or manage Sergio memory under scope and audience policy: pause

Capability: ai.agent.use. Kind: write.

Field In Type Required
Idempotency-Key header string yes
audience body “shared” / “member” no
baseVersion body integer no
confirmed body boolean no
conversationId body string no
cursor body string no
id body string no
instructions body string no
kind body “decision” / “fact” / “preference” / “open_item” no
limit body integer no
scope body { kind: “project” / “client”, id: string } no
sources body array<{ source: object, sourceVersion: integer }> no
summary body string no
summaryEntries body array<{ id: string, version: integer }> no
text body string no

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { id: string, scope: { kind: “project” / “client”, id: string } or { kind: “workspace” }, audience: “shared” / “member”, summary: string, instructions: string, editable: boolean, paused: boolean, counts: { decision: integer, fact: integer, preference: integer, open_item: integer }, updatedAt: string, updatedBy: string or null, version: integer }.

POST /sergio/memory/reevaluate

Read or manage Sergio memory under scope and audience policy: reevaluate

Capability: ai.agent.use. Kind: write.

Field In Type Required
Idempotency-Key header string yes
audience body “shared” / “member” no
baseVersion body integer no
confirmed body boolean no
conversationId body string no
cursor body string no
id body string no
instructions body string no
kind body “decision” / “fact” / “preference” / “open_item” no
limit body integer no
scope body { kind: “project” / “client”, id: string } no
sources body array<{ source: object, sourceVersion: integer }> no
summary body string no
summaryEntries body array<{ id: string, version: integer }> no
text body string no

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { id: string, version: integer, examined: integer, restored: integer, nextCursor: string or null }.

POST /sergio/memory/reset

Read or manage Sergio memory under scope and audience policy: reset

Capability: ai.agent.use. Kind: write.

Field In Type Required
Idempotency-Key header string yes
audience body “shared” / “member” no
baseVersion body integer no
confirmed body boolean no
conversationId body string no
cursor body string no
id body string no
instructions body string no
kind body “decision” / “fact” / “preference” / “open_item” no
limit body integer no
scope body { kind: “project” / “client”, id: string } no
sources body array<{ source: object, sourceVersion: integer }> no
summary body string no
summaryEntries body array<{ id: string, version: integer }> no
text body string no

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { id: string, version: integer }.

POST /sergio/memory/resume

Read or manage Sergio memory under scope and audience policy: resume

Capability: ai.agent.use. Kind: write.

Field In Type Required
Idempotency-Key header string yes
audience body “shared” / “member” no
baseVersion body integer no
confirmed body boolean no
conversationId body string no
cursor body string no
id body string no
instructions body string no
kind body “decision” / “fact” / “preference” / “open_item” no
limit body integer no
scope body { kind: “project” / “client”, id: string } no
sources body array<{ source: object, sourceVersion: integer }> no
summary body string no
summaryEntries body array<{ id: string, version: integer }> no
text body string no

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { id: string, scope: { kind: “project” / “client”, id: string } or { kind: “workspace” }, audience: “shared” / “member”, summary: string, instructions: string, editable: boolean, paused: boolean, counts: { decision: integer, fact: integer, preference: integer, open_item: integer }, updatedAt: string, updatedBy: string or null, version: integer }.

POST /sergio/memory/summary/set

Read or manage Sergio memory under scope and audience policy: summary.set

Capability: ai.agent.use. Kind: write.

Field In Type Required
Idempotency-Key header string yes
audience body “shared” / “member” no
baseVersion body integer no
confirmed body boolean no
conversationId body string no
cursor body string no
id body string no
instructions body string no
kind body “decision” / “fact” / “preference” / “open_item” no
limit body integer no
scope body { kind: “project” / “client”, id: string } no
sources body array<{ source: object, sourceVersion: integer }> no
summary body string no
summaryEntries body array<{ id: string, version: integer }> no
text body string no

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { id: string, scope: { kind: “project” / “client”, id: string } or { kind: “workspace” }, audience: “shared” / “member”, summary: string, instructions: string, editable: boolean, paused: boolean, counts: { decision: integer, fact: integer, preference: integer, open_item: integer }, updatedAt: string, updatedBy: string or null, version: integer }.

POST /sergio/memory/suppressions/clear

Read or manage Sergio memory under scope and audience policy: suppressions.clear

Capability: ai.agent.use. Kind: write.

Field In Type Required
Idempotency-Key header string yes
audience body “shared” / “member” no
baseVersion body integer no
confirmed body boolean no
conversationId body string no
cursor body string no
id body string no
instructions body string no
kind body “decision” / “fact” / “preference” / “open_item” no
limit body integer no
scope body { kind: “project” / “client”, id: string } no
sources body array<{ source: object, sourceVersion: integer }> no
summary body string no
summaryEntries body array<{ id: string, version: integer }> no
text body string no

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { id: string, scope: { kind: “project” / “client”, id: string } or { kind: “workspace” }, audience: “shared” / “member”, summary: string, instructions: string, editable: boolean, paused: boolean, counts: { decision: integer, fact: integer, preference: integer, open_item: integer }, updatedAt: string, updatedBy: string or null, version: integer }.

POST /sergio/conversations/{id}/messages

Append a user message to your private conversation

Capability: ai.agent.use. Kind: write.

Field In Type Required
id path string yes
fileIds body array no
parentMessageId body string no
text body string yes

Output: { id: string, conversationId: string, parentMessageId: string or null, role: “user” / “assistant”, parts: array, status: “streaming” / “done” / “stopped” / “error”, createdAt: string, creditsUsed: number, model: string or null }.

POST /sergio/messages/{messageId}/edit

Edit your message: a new version and a fresh answer

Capability: ai.agent.use. Kind: write.

Field In Type Required
messageId path string yes
text body string yes
tier body “fast” / “smart” no

Output: { runId: string, userMessage: { id: string, conversationId: string, parentMessageId: string or null, role: “user” / “assistant”, parts: array, status: “streaming” / “done” / “stopped” / “error”, createdAt: string, creditsUsed: number, model: string or null } or null, assistantMessage: { id: string, conversationId: string, parentMessageId: string or null, role: “user” / “assistant”, parts: array, status: “streaming” / “done” / “stopped” / “error”, createdAt: string, creditsUsed: number, model: string or null } or null, heldCredits: integer }.

POST /sergio/messages/{messageId}/retry

Answer again: a new version of a Sergio answer

Capability: ai.agent.use. Kind: write.

Field In Type Required
messageId path string yes
tier body “fast” / “smart” no

Output: { runId: string, userMessage: { id: string, conversationId: string, parentMessageId: string or null, role: “user” / “assistant”, parts: array, status: “streaming” / “done” / “stopped” / “error”, createdAt: string, creditsUsed: number, model: string or null } or null, assistantMessage: { id: string, conversationId: string, parentMessageId: string or null, role: “user” / “assistant”, parts: array, status: “streaming” / “done” / “stopped” / “error”, createdAt: string, creditsUsed: number, model: string or null } or null, heldCredits: integer }.

POST /sergio/conversations/{id}/send

Send a message to Sergio and start streaming the answer

Capability: ai.agent.use. Kind: write.

Field In Type Required
id path string yes
fileIds body array no
parentMessageId body string no
text body string yes
tier body “fast” / “smart” no
via body “text” / “voice” no

Output: { runId: string, userMessage: { id: string, conversationId: string, parentMessageId: string or null, role: “user” / “assistant”, parts: array, status: “streaming” / “done” / “stopped” / “error”, createdAt: string, creditsUsed: number, model: string or null } or null, assistantMessage: { id: string, conversationId: string, parentMessageId: string or null, role: “user” / “assistant”, parts: array, status: “streaming” / “done” / “stopped” / “error”, createdAt: string, creditsUsed: number, model: string or null } or null, heldCredits: integer }.

POST /sergio/messages/{messageId}/stop

Stop a streaming Sergio answer

Capability: ai.agent.use. Kind: write.

Field In Type Required
messageId path string yes

Output: { runId: string, stopped: boolean }.

POST /sergio/proposals/{proposalId}/decide

Confirm, cancel or undo your Sergio tool proposal using its existing confirmation and undo rules.

Capability: ai.agent.use. Kind: write.

Field In Type Required
proposalId path string yes
decision body “confirm” / “cancel” / “undo” yes

Output: { id: string, actionId: string, state: “pending” / “confirmed” / “cancelled” / “expired” / “undone”, preview: { now: object, after: object }, createdAt: number, expiresAt: number, undoUntil: number or null, canUndo: boolean, undoSupported?: boolean }.

GET /sergio/proposals/{proposalId}

Read your Sergio tool proposal and its current decision state.

Capability: ai.agent.use. Kind: read.

Field In Type Required
proposalId path string yes

Output: { id: string, actionId: string, state: “pending” / “confirmed” / “cancelled” / “expired” / “undone”, preview: { now: object, after: object }, createdAt: number, expiresAt: number, undoUntil: number or null, canUndo: boolean, undoSupported?: boolean }.

srvo

GET /srvo/settings

Read the workspace SRVO default. Unavailable or narrowed dashboards fall back to Overview.

Capability: srvo.settings.read. Kind: read.

No input fields.

Output: { defaultDashboardId: string or null }.

PUT /srvo/settings

Set the workspace SRVO default to a Workspace dashboard or Overview. Human owner/admin only.

Capability: srvo.settings.manage. Kind: write.

Field In Type Required
defaultDashboardId body string or null yes

Output: { defaultDashboardId: string or null }.

structure

POST /dashboards/{dashboardId}/widgets

Add one widget to dashboardId at optional baseVersion. Returns the saved layout; maximum 40 widgets.

Capability: structure.items.edit. Kind: write.

Field In Type Required
dashboardId path string yes
baseVersion body integer no
widget body { family?: “metric”, id?: string, kind: “kpi” / “progress” / “bar” / “line” / “stacked” / “table” / “donut”, title?: string, tableId: string, metrics: array, groupField?: string, dateField?: string, bucket?: “day” / “week” / “month”, range: “all” / “thisWeek” / “lastWeek” / “thisMonth” / “lastMonth” / “last7” / “last30” / “last90” / “last365”, compare?: boolean, size?: { w: integer, h: integer }, segmentField?: string, stackMode?: “stacked” / “grouped”, area?: boolean, topN?: integer, target?: number, targetMode?: “goal” / “limit”, filters?: array } or { family: “module”, id?: string, kind: “greeting” / “recents” / “myTasks” / “inbox” / “trackWeek” / “favourites” / “quickActions”, title?: string, size?: { w: integer, h: integer } } or { family: “script”, id?: string, scriptId: string, widgetKey: string, title?: string, size?: { w: integer, h: integer } } yes

Output: { dashboardId: string, widgets: array, version: integer, canEdit: boolean, changeId: integer }.

POST /dashboards

Create a dashboard with title and up to 40 widgets. Optional parentId/spaceId controls inherited access; top level is private. Returns the dashboard.

Capability: structure.items.edit. Kind: write.

Field In Type Required
parentId body string or null no
spaceId body string no
title body string yes
widgets body array<{ family?: “metric”, id?: string, kind: “kpi” / “progress” / “bar” / “line” / “stacked” / “table” / “donut”, title?: string, tableId: string, metrics: array, groupField?: string, dateField?: string, bucket?: “day” / “week” / “month”, range: “all” / “thisWeek” / “lastWeek” / “thisMonth” / “lastMonth” / “last7” / “last30” / “last90” / “last365”, compare?: boolean, size?: object, segmentField?: string, stackMode?: “stacked” / “grouped”, area?: boolean, topN?: integer, target?: number, targetMode?: “goal” / “limit”, filters?: array } or { family: “module”, id?: string, kind: “greeting” / “recents” / “myTasks” / “inbox” / “trackWeek” / “favourites” / “quickActions”, title?: string, size?: object } or { family: “script”, id?: string, scriptId: string, widgetKey: string, title?: string, size?: object }> no

Output: { dashboardId: string, widgets: array, version: integer, canEdit: boolean, changeId: integer, title: string }.

POST /dashboards/reports

Create a weekly or monthly report dashboard with up to 40 widgets. Optional range defaults to last full period. Returns dashboard and report metadata; no delivery.

Capability: structure.items.edit. Kind: write.

Field In Type Required
cadence body “weekly” / “monthly” yes
parentId body string or null no
range body “all” / “thisWeek” / “lastWeek” / “thisMonth” / “lastMonth” / “last7” / “last30” / “last90” / “last365” no
spaceId body string no
title body string yes
widgets body array<{ family?: “metric”, id?: string, kind: “kpi” / “progress” / “bar” / “line” / “stacked” / “table” / “donut”, title?: string, tableId: string, metrics: array, groupField?: string, dateField: string, bucket?: “day” / “week” / “month”, compare?: boolean, size?: object, segmentField?: string, stackMode?: “stacked” / “grouped”, area?: boolean, topN?: integer, target?: number, targetMode?: “goal” / “limit”, filters?: array }> yes

Output: { dashboardId: string, widgets: array, version: integer, canEdit: boolean, changeId: integer, title: string, report: { cadence: “weekly” / “monthly”, range: “all” / “thisWeek” / “lastWeek” / “thisMonth” / “lastMonth” / “last7” / “last30” / “last90” / “last365”, schedule: null } }.

POST /dashboards/{dashboardId}/discard

Move a dashboard created by Sergio to the trash while its widgets are unchanged (Undo).

Capability: structure.items.edit. Kind: write.

Field In Type Required
dashboardId path string yes
baseVersion body integer yes

Output: { dashboardId: string, trashed: true }.

PATCH /dashboards/{dashboardId}/widgets

Add, update or remove dashboard widgets by dashboardId and optional baseVersion. Returns the saved layout; maximum 40 widgets.

Capability: structure.items.edit. Kind: write.

Field In Type Required
dashboardId path string yes
add body array<{ family?: “metric”, id?: string, kind: “kpi” / “progress” / “bar” / “line” / “stacked” / “table” / “donut”, title?: string, tableId: string, metrics: array, groupField?: string, dateField?: string, bucket?: “day” / “week” / “month”, range: “all” / “thisWeek” / “lastWeek” / “thisMonth” / “lastMonth” / “last7” / “last30” / “last90” / “last365”, compare?: boolean, size?: object, segmentField?: string, stackMode?: “stacked” / “grouped”, area?: boolean, topN?: integer, target?: number, targetMode?: “goal” / “limit”, filters?: array } or { family: “module”, id?: string, kind: “greeting” / “recents” / “myTasks” / “inbox” / “trackWeek” / “favourites” / “quickActions”, title?: string, size?: object } or { family: “script”, id?: string, scriptId: string, widgetKey: string, title?: string, size?: object }> no
baseVersion body integer no
remove body array no
update body array<{ family?: “metric”, id: string, kind: “kpi” / “progress” / “bar” / “line” / “stacked” / “table” / “donut”, title?: string, tableId: string, metrics: array, groupField?: string, dateField?: string, bucket?: “day” / “week” / “month”, range: “all” / “thisWeek” / “lastWeek” / “thisMonth” / “lastMonth” / “last7” / “last30” / “last90” / “last365”, compare?: boolean, size?: object, segmentField?: string, stackMode?: “stacked” / “grouped”, area?: boolean, topN?: integer, target?: number, targetMode?: “goal” / “limit”, filters?: array } or { family: “module”, id: string, kind: “greeting” / “recents” / “myTasks” / “inbox” / “trackWeek” / “favourites” / “quickActions”, title?: string, size?: object } or { family: “script”, id: string, scriptId: string, widgetKey: string, title?: string, size?: object }> no

Output: { dashboardId: string, widgets: array, version: integer, canEdit: boolean, changeId: integer }.

GET /dashboards/{dashboardId}

Read a dashboard’s saved widgets (the ones on tables the caller can see) and its version.

Capability: structure.tree.read. Kind: read.

Field In Type Required
dashboardId path string yes

Output: { dashboardId: string, widgets: array, version: integer, canEdit: boolean }.

PUT /dashboards/{dashboardId}

Replace a dashboard’s widgets (max 40; family metric, module or script). Send the version you read as baseVersion; a newer save returns CONFLICT.

Capability: structure.items.edit. Kind: write.

Field In Type Required
dashboardId path string yes
baseVersion body integer yes
widgets body array<{ family?: “metric”, id: string, kind: “kpi” / “progress” / “bar” / “line” / “stacked” / “table” / “donut”, title?: string, tableId: string, metrics: array, groupField?: string, dateField?: string, bucket?: “day” / “week” / “month”, range: “all” / “thisWeek” / “lastWeek” / “thisMonth” / “lastMonth” / “last7” / “last30” / “last90” / “last365”, compare?: boolean, size?: object, segmentField?: string, stackMode?: “stacked” / “grouped”, area?: boolean, topN?: integer, target?: number, targetMode?: “goal” / “limit”, filters?: array } or { family: “module”, id: string, kind: “greeting” / “recents” / “myTasks” / “inbox” / “trackWeek” / “favourites” / “quickActions”, title?: string, size?: object } or { family: “script”, id: string, scriptId: string, widgetKey: string, title?: string, size?: object }> yes

Output: { dashboardId: string, widgets: array, version: integer, canEdit: boolean, changeId: integer }.

PUT /items/{itemId}/favourite

Add an item to the caller’s favourites (last).

Capability: structure.favourites.edit. Kind: write.

Field In Type Required
itemId path string yes

Output: { itemId: string, favourite: boolean, rank: string or null, changeId: integer }.

DELETE /items/{itemId}/favourite

Remove an item from the caller’s favourites.

Capability: structure.favourites.edit. Kind: write.

Field In Type Required
itemId path string yes

Output: { itemId: string, favourite: boolean, rank: string or null, changeId: integer }.

PUT /views/{viewId}/favourite

Favourite a visible view for this member.

Capability: structure.favourites.edit. Kind: write.

Field In Type Required
viewId path string yes

Output: { viewId: string, favourite: boolean, rank: string or null, changeId: integer }.

DELETE /views/{viewId}/favourite

Remove a personal view favourite.

Capability: structure.favourites.edit. Kind: write.

Field In Type Required
viewId path string yes

Output: { viewId: string, favourite: boolean, rank: string or null, changeId: integer }.

POST /tables/{tableId}/fields/{fid}/convert

Change a field’s type and convert every value. Preview shows how many values convert, need review or are lost; then commit.

Capability: structure.fields.edit. Kind: destructive.

Field In Type Required
tableId path string yes
fid path string yes
Srvo-Confirmation header string no
config body object no
type body “title” / “text” / “long_text” / “number” / “currency” / “select” / “multi_select” / “status” / “checkbox” / “date” / “duration” / “person” / “files” / “url” / “email” / “phone” / “rating” / “progress” / “auto_number” / “created_time” / “updated_time” / “created_by” / “updated_by” / “link” / “subtasks” / “note” / “lookup” / “rollup” / “formula” / “time_tracked” / “estimate” yes

Srvo-Confirmation: Without it the call returns a preview and a token; send the token back to commit.

Output: { field: { id: string, fid: string, tableId: string, name: string, type: “title” / “text” / “long_text” / “number” / “currency” / “select” / “multi_select” / “status” / “checkbox” / “date” / “duration” / “person” / “files” / “url” / “email” / “phone” / “rating” / “progress” / “auto_number” / “created_time” / “updated_time” / “created_by” / “updated_by” / “link” / “subtasks” / “note” / “lookup” / “rollup” / “formula” / “time_tracked” / “estimate”, config: object, rank: string, required: boolean, description: string or null, system: boolean, systemRole: string or null, version: integer }, counts: { converted: integer, lost: integer, review: integer }, changeId: integer } or { preview: { summary: string, counts: object, warnings: array }, confirmationToken: string, expiresAt: string }.

POST /tables/{tableId}/fields

Add a field to a table. Config is validated per type; formulas are type-checked.

Capability: structure.fields.edit. Kind: write.

Field In Type Required
tableId path string yes
Idempotency-Key header string no
beforeFid body string or null no
config body object no
description body string or null no
fid body string no
id body string no
name body string yes
required body boolean no
type body “title” / “text” / “long_text” / “number” / “currency” / “select” / “multi_select” / “status” / “checkbox” / “date” / “duration” / “person” / “files” / “url” / “email” / “phone” / “rating” / “progress” / “auto_number” / “created_time” / “updated_time” / “created_by” / “updated_by” / “link” / “subtasks” / “note” / “lookup” / “rollup” / “formula” / “time_tracked” / “estimate” yes

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { field: { id: string, fid: string, tableId: string, name: string, type: “title” / “text” / “long_text” / “number” / “currency” / “select” / “multi_select” / “status” / “checkbox” / “date” / “duration” / “person” / “files” / “url” / “email” / “phone” / “rating” / “progress” / “auto_number” / “created_time” / “updated_time” / “created_by” / “updated_by” / “link” / “subtasks” / “note” / “lookup” / “rollup” / “formula” / “time_tracked” / “estimate”, config: object, rank: string, required: boolean, description: string or null, system: boolean, systemRole: string or null, version: integer }, changeId: integer }.

POST /tables/{tableId}/fields/{fid}/trash

Move a field to the trash (its values stay in the records). Preview first, then commit.

Capability: structure.fields.edit. Kind: destructive.

Field In Type Required
tableId path string yes
fid path string yes
Srvo-Confirmation header string no

Srvo-Confirmation: Without it the call returns a preview and a token; send the token back to commit.

Output: { fid: string, trashedAt: string, changeId: integer } or { preview: { summary: string, counts: object, warnings: array }, confirmationToken: string, expiresAt: string }.

GET /tables/{tableId}/fields

The fields of a table, in order (fields hidden from the caller are left out).

Capability: structure.tree.read. Kind: read.

Field In Type Required
tableId path string yes

Output: { items: array }.

PATCH /tables/{tableId}/fields/{fid}

Rename a field, edit its description, required flag, order or same-type config.

Capability: structure.fields.edit. Kind: write.

Field In Type Required
tableId path string yes
fid path string yes
beforeFid body string or null no
config body object no
description body string or null no
name body string no
required body boolean no

Output: { field: { id: string, fid: string, tableId: string, name: string, type: “title” / “text” / “long_text” / “number” / “currency” / “select” / “multi_select” / “status” / “checkbox” / “date” / “duration” / “person” / “files” / “url” / “email” / “phone” / “rating” / “progress” / “auto_number” / “created_time” / “updated_time” / “created_by” / “updated_by” / “link” / “subtasks” / “note” / “lookup” / “rollup” / “formula” / “time_tracked” / “estimate”, config: object, rank: string, required: boolean, description: string or null, system: boolean, systemRole: string or null, version: integer }, changeId: integer }.

POST /tables/{tableId}/forms

Create a form on a Boards table. Each question maps to one table field. Returns the form, unpublished. Send an idempotencyKey to make retries safe.

Capability: structure.views.edit. Kind: write.

Field In Type Required
tableId path string yes
Idempotency-Key header string yes
definition body { title: string, description?: string, questions: array, thankYou?: string, closeDate?: string or null, responseLimit?: integer } yes
id body string no

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { form: { title: string, description: string, questions: array, thankYou: string, closeDate: string or null, responseLimit: integer, id: string, tableId: string, spaceId: string, version: integer, slug: string, published: boolean, trashed: boolean, submissions: integer, canEdit: boolean } }.

GET /forms/{formId}

Get one form’s definition: title, questions and their board fields, and publish state. Forms that use a field hidden from you return NOT_FOUND.

Capability: structure.tree.read. Kind: read.

Field In Type Required
formId path string yes

Output: { form: { title: string, description: string, questions: array, thankYou: string, closeDate: string or null, responseLimit: integer, id: string, tableId: string, spaceId: string, version: integer, slug: string, published: boolean, trashed: boolean, submissions: integer, canEdit: boolean } }.

GET /tables/{tableId}/forms

List the forms of one Boards table (tableId) that you can read, with their definitions. Not paginated.

Capability: structure.tree.read. Kind: read.

Field In Type Required
tableId path string yes
trash query boolean no

Output: { items: array }.

POST /forms/{formId}/publish

Publish a form so its public link accepts submissions, which are saved as records under your authority.

Capability: structure.views.edit. Kind: write.

Field In Type Required
formId path string yes
Idempotency-Key header string yes
baseVersion body integer yes

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { form: { title: string, description: string, questions: array, thankYou: string, closeDate: string or null, responseLimit: integer, id: string, tableId: string, spaceId: string, version: integer, slug: string, published: boolean, trashed: boolean, submissions: integer, canEdit: boolean } }.

POST /forms/{formId}/restore

Restore a form as an unpublished draft.

Capability: structure.views.edit. Kind: destructive.

Field In Type Required
formId path string yes
Idempotency-Key header string yes
Srvo-Confirmation header string no
baseVersion body integer yes

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Srvo-Confirmation: Without it the call returns a preview and a token; send the token back to commit.

Output: { form: { title: string, description: string, questions: array, thankYou: string, closeDate: string or null, responseLimit: integer, id: string, tableId: string, spaceId: string, version: integer, slug: string, published: boolean, trashed: boolean, submissions: integer, canEdit: boolean } } or { preview: { summary: string, counts: object, warnings: array }, confirmationToken: string, expiresAt: string }.

GET /forms/{formId}/submissions

List a form’s submissions as record ids and submit times, in a stable order. Only records you can read are returned, so a page may hold fewer than limit; read each with getRecord. Paginated: pass next as after until it is null.

Capability: structure.tree.read. Kind: read.

Field In Type Required
formId path string yes
after query string no
limit query integer no

Output: { items: array, next: string or null }.

POST /forms/{formId}/trash

Move a form to trash and disable its public link.

Capability: structure.views.edit. Kind: destructive.

Field In Type Required
formId path string yes
Idempotency-Key header string yes
Srvo-Confirmation header string no
baseVersion body integer yes

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Srvo-Confirmation: Without it the call returns a preview and a token; send the token back to commit.

Output: { form: { title: string, description: string, questions: array, thankYou: string, closeDate: string or null, responseLimit: integer, id: string, tableId: string, spaceId: string, version: integer, slug: string, published: boolean, trashed: boolean, submissions: integer, canEdit: boolean } } or { preview: { summary: string, counts: object, warnings: array }, confirmationToken: string, expiresAt: string }.

POST /forms/{formId}/unpublish

Unpublish a form so its public link stops accepting submissions.

Capability: structure.views.edit. Kind: write.

Field In Type Required
formId path string yes
Idempotency-Key header string yes
baseVersion body integer yes

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { form: { title: string, description: string, questions: array, thankYou: string, closeDate: string or null, responseLimit: integer, id: string, tableId: string, spaceId: string, version: integer, slug: string, published: boolean, trashed: boolean, submissions: integer, canEdit: boolean } }.

PATCH /forms/{formId}

Replace a form’s definition. Pass the form’s version as baseVersion. A published form is unpublished and must be published again.

Capability: structure.views.edit. Kind: write.

Field In Type Required
formId path string yes
Idempotency-Key header string yes
baseVersion body integer yes
definition body { title: string, description?: string, questions: array, thankYou?: string, closeDate?: string or null, responseLimit?: integer } yes

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { form: { title: string, description: string, questions: array, thankYou: string, closeDate: string or null, responseLimit: integer, id: string, tableId: string, spaceId: string, version: integer, slug: string, published: boolean, trashed: boolean, submissions: integer, canEdit: boolean } }.

POST /items

Create a folder, table, page, dashboard or form in a space. Tables get their primary Title field.

Capability: structure.items.edit. Kind: write.

Field In Type Required
Idempotency-Key header string no
audience body “private” / “workspace” no
beforeId body string or null no
icon body string or null no
id body string no
kind body “folder” / “table” / “page” / “dashboard” / “form” yes
module body “boards” / “notes” / “files” / “srvo” no
parentId body string or null no
private body boolean no
spaceId body string no
title body string yes
workspaceRole body “viewer” / “commenter” / “editor” / “owner” no

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { item: { id: string, spaceId?: string, parentId: string or null, kind: “folder” / “table” / “page” / “dashboard” / “form” / “file_folder”, title: string, icon: string or null, rank: string, module: string, visibility: “inherit” / “private”, createdBy: string or null, updatedAt: string, deletedAt: string or null, version: integer, ownerId?: string or null, audience?: “private” / “shared” / “workspace”, myRole?: “viewer” / “commenter” / “editor” / “owner”, canShare?: boolean, parentVisible?: boolean, section?: “private” / “shared” / “workspace” }, primaryField: { id: string, fid: string, tableId: string, name: string, type: “title” / “text” / “long_text” / “number” / “currency” / “select” / “multi_select” / “status” / “checkbox” / “date” / “duration” / “person” / “files” / “url” / “email” / “phone” / “rating” / “progress” / “auto_number” / “created_time” / “updated_time” / “created_by” / “updated_by” / “link” / “subtasks” / “note” / “lookup” / “rollup” / “formula” / “time_tracked” / “estimate”, config: object, rank: string, required: boolean, description: string or null, system: boolean, systemRole: string or null, version: integer } or null, changeId: integer }.

POST /items/{itemId}/move

Move an item (with everything under it) to another parent or space.

Capability: structure.items.edit. Kind: write.

Field In Type Required
itemId path string yes
beforeId body string or null no
confirmToken body string no
parentId body string or null yes
spaceId body string no

Output: { item: { id: string, spaceId?: string, parentId: string or null, kind: “folder” / “table” / “page” / “dashboard” / “form” / “file_folder”, title: string, icon: string or null, rank: string, module: string, visibility: “inherit” / “private”, createdBy: string or null, updatedAt: string, deletedAt: string or null, version: integer, ownerId?: string or null, audience?: “private” / “shared” / “workspace”, myRole?: “viewer” / “commenter” / “editor” / “owner”, canShare?: boolean, parentVisible?: boolean, section?: “private” / “shared” / “workspace” }, changeId: integer } or { preview: { gains: array, losses: array, itemCount: integer }, confirmToken: string }.

POST /items/{itemId}/reorder

Put an item before a sibling (beforeId) or last (null).

Capability: structure.items.edit. Kind: write.

Field In Type Required
itemId path string yes
beforeId body string or null yes

Output: { item: { id: string, spaceId?: string, parentId: string or null, kind: “folder” / “table” / “page” / “dashboard” / “form” / “file_folder”, title: string, icon: string or null, rank: string, module: string, visibility: “inherit” / “private”, createdBy: string or null, updatedAt: string, deletedAt: string or null, version: integer, ownerId?: string or null, audience?: “private” / “shared” / “workspace”, myRole?: “viewer” / “commenter” / “editor” / “owner”, canShare?: boolean, parentVisible?: boolean, section?: “private” / “shared” / “workspace” }, changeId: integer }.

POST /items/{itemId}/restore

Restore a trashed item and its contents. Preview first, then confirm.

Capability: structure.items.edit. Kind: destructive.

Field In Type Required
itemId path string yes
Srvo-Confirmation header string no

Srvo-Confirmation: Without it the call returns a preview and a token; send the token back to commit.

Output: { item: { id: string, spaceId?: string, parentId: string or null, kind: “folder” / “table” / “page” / “dashboard” / “form” / “file_folder”, title: string, icon: string or null, rank: string, module: string, visibility: “inherit” / “private”, createdBy: string or null, updatedAt: string, deletedAt: string or null, version: integer, ownerId?: string or null, audience?: “private” / “shared” / “workspace”, myRole?: “viewer” / “commenter” / “editor” / “owner”, canShare?: boolean, parentVisible?: boolean, section?: “private” / “shared” / “workspace” }, changeId: integer } or { preview: { summary: string, counts: object, warnings: array }, confirmationToken: string, expiresAt: string }.

GET /items/{itemId}/share

Who can open an item and why: owner, people, teams, clients, workspace, inherited folders.

Capability: structure.tree.read. Kind: read.

Field In Type Required
itemId path string yes

Output: { itemId: string, version: integer, owner: { id: string, name: string, active: boolean } or null, audience: “private” / “shared” / “workspace”, workspaceRole: “viewer” / “commenter” / “editor” / “owner” or null, grants: array, hiddenCount?: integer, myRole: “viewer” / “commenter” / “editor” / “owner”, canManage: boolean }.

POST /items/{itemId}/share

Share an item with people, teams, clients or the whole workspace, or change or remove access.

Capability: structure.items.share. Kind: write.

Field In Type Required
itemId path string yes
add body array<{ subject: object, role: “viewer” / “commenter” / “editor” / “owner” }> no
baseVersion body integer yes
confirmToken body string no
notify body { message?: string } no
remove body array no
update body array<{ grantId: string, role: “viewer” / “commenter” / “editor” / “owner” }> no
workspace body “viewer” / “commenter” / “editor” / “owner” or null no

Output: { share: { itemId: string, version: integer, owner: object or null, audience: “private” / “shared” / “workspace”, workspaceRole: “viewer” / “commenter” / “editor” / “owner” or null, grants: array, hiddenCount?: integer, myRole: “viewer” / “commenter” / “editor” / “owner”, canManage: boolean }, changeId: number } or { preview: { gains: array, losses: array, itemCount: integer }, confirmToken: string }.

POST /items/{itemId}/transfer-ownership

Make another workspace member the owner of an item; the previous owner keeps edit access.

Capability: structure.items.share. Kind: write.

Field In Type Required
itemId path string yes
baseVersion body integer yes
confirmToken body string no
toMemberId body string yes

Output: { share: { itemId: string, version: integer, owner: object or null, audience: “private” / “shared” / “workspace”, workspaceRole: “viewer” / “commenter” / “editor” / “owner” or null, grants: array, hiddenCount?: integer, myRole: “viewer” / “commenter” / “editor” / “owner”, canManage: boolean }, changeId: number } or { preview: { gains: array, losses: array, itemCount: integer }, confirmToken: string }.

POST /items/{itemId}/trash

Move an item and everything under it to the trash (restorable for 30 days). Preview first, then commit.

Capability: structure.items.edit. Kind: destructive.

Field In Type Required
itemId path string yes
Srvo-Confirmation header string no

Srvo-Confirmation: Without it the call returns a preview and a token; send the token back to commit.

Output: { itemId: string, trashedAt: string, changeId: integer } or { preview: { summary: string, counts: object, warnings: array }, confirmationToken: string, expiresAt: string }.

GET /trash/items

Items in the trash the caller can see (newest first).

Capability: structure.tree.read. Kind: read.

Field In Type Required
module query “boards” / “notes” / “files” / “srvo” no

Output: { items: array }.

PATCH /items/{itemId}

Rename an item or change its icon.

Capability: structure.items.edit. Kind: write.

Field In Type Required
itemId path string yes
icon body string or null no
title body string no

Output: { item: { id: string, spaceId?: string, parentId: string or null, kind: “folder” / “table” / “page” / “dashboard” / “form” / “file_folder”, title: string, icon: string or null, rank: string, module: string, visibility: “inherit” / “private”, createdBy: string or null, updatedAt: string, deletedAt: string or null, version: integer, ownerId?: string or null, audience?: “private” / “shared” / “workspace”, myRole?: “viewer” / “commenter” / “editor” / “owner”, canShare?: boolean, parentVisible?: boolean, section?: “private” / “shared” / “workspace” }, changeId: integer }.

GET /recents

Visible personal recents, newest first. At most 100 entries retained for 90 days.

Capability: structure.tree.read. Kind: read.

Field In Type Required
limit query integer no

Output: { items: array }.

POST /recents/{itemId}

Remember a visible item for this member, pruning old and excess recents.

Capability: structure.tree.read. Kind: write.

Field In Type Required
itemId path string yes

Output: { itemId: string, at: string, changeId: integer }.

POST /spaces

Create a space in a team (admins).

Capability: structure.spaces.manage. Kind: write.

Field In Type Required
Idempotency-Key header string no
color body string no
icon body string or null no
id body string no
name body string yes
teamId body string yes

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { space: { id: string, teamId: string, kind: “team” / “personal”, name: string, icon: string or null, color: string or null, visibility: “team” / “private”, rank: string, canEdit: boolean, version: integer }, changeId: integer }.

POST /spaces/{spaceId}/move

Move a space to another team. Preview lists members gaining or losing access.

Capability: structure.spaces.manage. Kind: destructive.

Field In Type Required
spaceId path string yes
Srvo-Confirmation header string no
teamId body string yes

Srvo-Confirmation: Without it the call returns a preview and a token; send the token back to commit.

Output: { space: { id: string, teamId: string, kind: “team” / “personal”, name: string, icon: string or null, color: string or null, visibility: “team” / “private”, rank: string, canEdit: boolean, version: integer }, changeId: integer } or { preview: { summary: string, counts: object, warnings: array }, confirmationToken: string, expiresAt: string }.

POST /spaces/{spaceId}/restore

Restore a space within 30 days, keeping prior child trash states.

Capability: structure.spaces.manage. Kind: destructive.

Field In Type Required
spaceId path string yes
Srvo-Confirmation header string no

Srvo-Confirmation: Without it the call returns a preview and a token; send the token back to commit.

Output: { space: { id: string, teamId: string, kind: “team” / “personal”, name: string, icon: string or null, color: string or null, visibility: “team” / “private”, rank: string, canEdit: boolean, version: integer }, changeId: integer } or { preview: { summary: string, counts: object, warnings: array }, confirmationToken: string, expiresAt: string }.

POST /spaces/{spaceId}/trash

Trash a space and its contents for 30 days. Preview first.

Capability: structure.spaces.manage. Kind: destructive.

Field In Type Required
spaceId path string yes
Srvo-Confirmation header string no

Srvo-Confirmation: Without it the call returns a preview and a token; send the token back to commit.

Output: { spaceId: string, trashedAt: string, changeId: integer } or { preview: { summary: string, counts: object, warnings: array }, confirmationToken: string, expiresAt: string }.

GET /trash/spaces

List trashed spaces for space managers.

Capability: structure.spaces.manage. Kind: read.

Field In Type Required
module query “boards” / “notes” / “files” / “srvo” no

Output: { spaces: array }.

PATCH /spaces/{spaceId}

Rename, re-icon, recolour or reorder a space (admins).

Capability: structure.spaces.manage. Kind: write.

Field In Type Required
spaceId path string yes
beforeId body string or null no
color body string or null no
icon body string or null no
name body string no

Output: { space: { id: string, teamId: string, kind: “team” / “personal”, name: string, icon: string or null, color: string or null, visibility: “team” / “private”, rank: string, canEdit: boolean, version: integer }, changeId: integer }.

POST /tables

Create a Boards table with its fields and views in one step (one undo). Start from a template (structure.templates.list) or pass fields and views. Private by default.

Capability: structure.items.edit. Kind: write.

Field In Type Required
Idempotency-Key header string no
audience body “private” / “workspace” no
fields body array<{ fid?: string, name: string, type: “text” / “long_text” / “number” / “currency” / “select” / “multi_select” / “status” / “checkbox” / “date” / “duration” / “person” / “files” / “url” / “email” / “phone” / “rating” / “progress” / “auto_number” / “created_time” / “updated_time” / “created_by” / “updated_by” / “link” / “subtasks” / “note” / “lookup” / “rollup” / “formula” / “time_tracked” / “estimate”, config?: object }> no
icon body string or null no
id body string no
parentId body string or null no
primaryName body string no
spaceId body string yes
templateId body “blank” / “projects” / “finances” / “todos” / “calendar” / “clients” no
title body string yes
views body array<{ type: “table” / “list” / “kanban” / “calendar” / “timeline” / “report” / “gallery” / “workload” / “mind_map” / “pivot” / “canvas”, name: string, config?: object }> no

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { item: { id: string, spaceId?: string, parentId: string or null, kind: “folder” / “table” / “page” / “dashboard” / “form” / “file_folder”, title: string, icon: string or null, rank: string, module: string, visibility: “inherit” / “private”, createdBy: string or null, updatedAt: string, deletedAt: string or null, version: integer, ownerId?: string or null, audience?: “private” / “shared” / “workspace”, myRole?: “viewer” / “commenter” / “editor” / “owner”, canShare?: boolean, parentVisible?: boolean, section?: “private” / “shared” / “workspace” }, fields: array, views: array, changeId: integer }.

GET /templates/boards

Board starting points (Blank, Projects, Finances, To-dos, Calendar / Events, Clients) with their fields and first view, for structure.tables.create.

Capability: structure.tree.read. Kind: read.

No input fields.

Output: { items: array }.

GET /tree

The sidebar tree: spaces, items and the caller’s favourites, as far as the caller can see.

Capability: structure.tree.read. Kind: read.

Field In Type Required
module query “boards” / “notes” / “files” / “srvo” no

Output: { structure?: “v2”, spaces: array, items: array, favourites: array, viewFavourites?: array }.

POST /tables/{tableId}/views

Save a new view of a table (shared, or personal with personal: true). Also how to copy a locked view.

Capability: structure.views.personal. Kind: write.

Field In Type Required
tableId path string yes
Idempotency-Key header string no
beforeId body string or null no
config body { filter?: { and: array } or { or: array } or { fid: string, op: “eq” / “neq” / “contains” / “not_contains” / “in” / “not_in” / “empty” / “not_empty” / “gt” / “gte” / “lt” / “lte”, value?: string or number or boolean or null or array or object, relative?: object } or null, sorts?: array, group?: array, fields?: array, card?: { coverFid: string or null, fids: array }, date?: { startFid: string, endFid: string or null, dependencyFid?: string }, wipLimits?: object, hiddenColumns?: array, columnSorts?: object, columnColors?: object, laneSum?: string or null, rowsBy?: string, colorBy?: string, rowHeight?: “short” / “medium” / “tall”, summaries?: object } no
id body string no
locked body boolean no
name body string yes
personal body boolean no
type body “table” / “list” / “kanban” / “calendar” / “timeline” / “report” / “gallery” / “workload” / “mind_map” / “pivot” / “canvas” yes

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { view: { id: string, tableId: string, type: “table” / “list” / “kanban” / “calendar” / “timeline” / “report” / “gallery” / “workload” / “mind_map” / “pivot” / “canvas”, name: string, ownerMemberId: string or null, createdBy: string or null, rank: string, locked: boolean, config: object, selectionStats: array<“count” / “sum” / “avg” / “min” / “max”>, canEdit: boolean, version: integer }, changeId: integer }.

DELETE /views/{viewId}

Delete a view (moves it to the trash; records are not touched).

Capability: structure.views.personal. Kind: destructive.

Field In Type Required
viewId path string yes
Srvo-Confirmation header string no

Srvo-Confirmation: Without it the call returns a preview and a token; send the token back to commit.

Output: { viewId: string, changeId: integer } or { preview: { summary: string, counts: object, warnings: array }, confirmationToken: string, expiresAt: string }.

GET /tables/{tableId}/views

The saved views of a table: shared ones plus the caller’s personal ones, in order.

Capability: structure.tree.read. Kind: read.

Field In Type Required
tableId path string yes

Output: { items: array }.

POST /views/{viewId}/reorder

Put a view before another (beforeId) or last (null). Locked views follow the lock rules.

Capability: structure.views.personal. Kind: write.

Field In Type Required
viewId path string yes
beforeId body string or null yes

Output: { view: { id: string, tableId: string, type: “table” / “list” / “kanban” / “calendar” / “timeline” / “report” / “gallery” / “workload” / “mind_map” / “pivot” / “canvas”, name: string, ownerMemberId: string or null, createdBy: string or null, rank: string, locked: boolean, config: object, selectionStats: array<“count” / “sum” / “avg” / “min” / “max”>, canEdit: boolean, version: integer }, changeId: integer }.

PUT /views/{viewId}/selection-stats

Save which statistics the caller sees for a selection in this view (per person; locks don’t apply).

Capability: structure.views.personal. Kind: write.

Field In Type Required
viewId path string yes
stats body array<“count” / “sum” / “avg” / “min” / “max”> yes

Output: { view: { id: string, tableId: string, type: “table” / “list” / “kanban” / “calendar” / “timeline” / “report” / “gallery” / “workload” / “mind_map” / “pivot” / “canvas”, name: string, ownerMemberId: string or null, createdBy: string or null, rank: string, locked: boolean, config: object, selectionStats: array<“count” / “sum” / “avg” / “min” / “max”>, canEdit: boolean, version: integer }, changeId: integer }.

PATCH /views/{viewId}

Change a view’s name, config (merged key by key) or lock. Locked views: only admins or their creator with the lock right; others save a copy.

Capability: structure.views.personal. Kind: write.

Field In Type Required
viewId path string yes
config body { filter?: { and: array } or { or: array } or { fid: string, op: “eq” / “neq” / “contains” / “not_contains” / “in” / “not_in” / “empty” / “not_empty” / “gt” / “gte” / “lt” / “lte”, value?: string or number or boolean or null or array or object, relative?: object } or null, sorts?: array, group?: array, fields?: array, card?: { coverFid: string or null, fids: array }, date?: { startFid: string, endFid: string or null, dependencyFid?: string }, wipLimits?: object, hiddenColumns?: array, columnSorts?: object, columnColors?: object, laneSum?: string or null, rowsBy?: string, colorBy?: string, rowHeight?: “short” / “medium” / “tall”, summaries?: object } no
locked body boolean no
name body string no

Output: { view: { id: string, tableId: string, type: “table” / “list” / “kanban” / “calendar” / “timeline” / “report” / “gallery” / “workload” / “mind_map” / “pivot” / “canvas”, name: string, ownerMemberId: string or null, createdBy: string or null, rank: string, locked: boolean, config: object, selectionStats: array<“count” / “sum” / “avg” / “min” / “max”>, canEdit: boolean, version: integer }, changeId: integer }.

support

POST /support/feedback

Send feedback to SRVO support

Capability: core.self.read. Kind: write.

Field In Type Required
errorId body string no
includeTechnicalDetails body boolean no
kind body “bug” / “idea” / “praise” yes
message body string yes
technicalDetails body { route?: string, release?: string, device?: { browser?: “chrome” / “safari” / “firefox” / “edge” / “other”, os?: “ios” / “macos” / “windows” / “android” / “linux” / “other”, type?: “phone” / “tablet” / “desktop” / “other” }, errors?: array } no

Output: { id: string }.

track

POST /track/entries

Create a completed manual time entry. Overlaps are allowed.

Capability: track.entries.create. Kind: write.

Field In Type Required
Idempotency-Key header string yes
billable body boolean no
clientRecordId body string or null no
description body string no
endAt body string yes
id body string no
memberId body string no
mentionedMemberIds body array no
note body string no
projectRecordId body string or null no
recordId body string or null no
startAt body string yes
tagIds body array no
timeZone body string yes

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { entry: { id: string, memberId: string, sessionId?: string or null, mentions?: array, version: integer, startAt: string, endAt: string or null, durationS: integer or null, description: string, recordId: string or null, projectRecordId: string or null, clientRecordId: string or null, tagIds: array, billable: boolean, note: string, timeZone: string, state: “draft” / “confirmed”, source: “timer” / “manual” / “import” / “agent” / “api”, deletedAt: string or null, invoicedAt: string or null }, changeId: integer }.

POST /track/entries/trash

Move time entries to trash. Preview and confirm the exact versions.

Capability: track.entries.delete. Kind: destructive.

Field In Type Required
Idempotency-Key header string no
Srvo-Confirmation header string no
entryIds body array yes
expectedVersions body object no

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Srvo-Confirmation: Without it the call returns a preview and a token; send the token back to commit.

Output: { entryIds: array, changeIds: array } or { preview: { summary: string, counts: object, warnings: array }, confirmationToken: string, expiresAt: string }.

POST /track/entries/export

Export own or permitted member/team time for the input date range with current rates and rounding. Returns filename, contentType and base64 body over MCP, up to 1 MiB; use REST for larger files. No paging.

Capability: track.entries.read. Kind: read.

Field In Type Required
billable body “yes” / “no” no
clientId body string no
entryIds body array no
format body “csv” / “xlsx” no
from body string yes
hours body “raw” / “rounded” / “both” no
invoiced body “yes” / “no” no
locale body “en” / “hu” no
memberId body string no
notes body “yes” / “no” no
projectId body string no
rounding body “rule” / “off” / “entry” / “report” no
scope body “own” / “accessible” no
tagId body string no
teamId body string no
timeZone body string yes
to body string yes

Output: string.

GET /track/entries/{entryId}

Get a visible time entry.

Capability: track.entries.read. Kind: read.

Field In Type Required
entryId path string yes
includeDeleted query boolean no

Output: { entry: { id: string, memberId: string, sessionId?: string or null, mentions?: array, version: integer, startAt: string, endAt: string or null, durationS: integer or null, description: string, recordId: string or null, projectRecordId: string or null, clientRecordId: string or null, tagIds: array, billable: boolean, note: string, timeZone: string, state: “draft” / “confirmed”, source: “timer” / “manual” / “import” / “agent” / “api”, deletedAt: string or null, invoicedAt: string or null } }.

GET /track/entries

List own time or explicitly permitted member/team time intersecting a UTC range.

Capability: track.entries.read. Kind: read.

Field In Type Required
scope query “own” / “accessible” no
from query string yes
to query string yes
timeZone query string yes
memberId query string no
teamId query string no
limit query integer no
cursor query string no

Output: { items: array, nextCursor: string or null }.

POST /track/entries/{entryId}/mentions

Invite memberIds to copy your confirmed entryId. Returns invitations; recipients keep independently editable copies. People only.

Capability: track.entries.update. Kind: write.

Field In Type Required
entryId path string yes
Idempotency-Key header string yes
memberIds body array yes

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { mentions: array, stoppedEntry?: { id: string, description: string } }.

POST /track/entries/{entryId}/restore

Restore a trashed entry by entryId and baseVersion. Returns the restored entry and changeId. People only.

Capability: track.entries.restore. Kind: write.

Field In Type Required
entryId path string yes
Idempotency-Key header string yes
baseVersion body integer yes

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { entry: { id: string, memberId: string, sessionId?: string or null, mentions?: array, version: integer, startAt: string, endAt: string or null, durationS: integer or null, description: string, recordId: string or null, projectRecordId: string or null, clientRecordId: string or null, tagIds: array, billable: boolean, note: string, timeZone: string, state: “draft” / “confirmed”, source: “timer” / “manual” / “import” / “agent” / “api”, deletedAt: string or null, invoicedAt: string or null }, changeId: integer }.

POST /track/entries/summary

Day/week and project/client totals in an explicit time zone. Drafts excluded; overlaps count independently.

Capability: track.entries.read. Kind: read.

Field In Type Required
from body string yes
memberId body string no
rounding body { mode?: “off” / “up” / “down” / “nearest”, stepS?: integer, apply?: “entry” / “report” } no
scope body “own” / “accessible” no
teamId body string no
timeZone body string yes
to body string yes

Output: { timeZone: string, asOf: string, totals: { rawS: integer, roundedS: integer, billableS: integer, nonBillableS: integer }, days: array, weeks: array, projects: array, clients: array }.

PATCH /track/entries/{entryId}

Update a time entry at baseVersion. Completed entries cannot become timers.

Capability: track.entries.update. Kind: write.

Field In Type Required
entryId path string yes
Idempotency-Key header string yes
baseVersion body integer yes
mentionedMemberIds body array no
patch body { description?: string, recordId?: string or null, projectRecordId?: string or null, clientRecordId?: string or null, tagIds?: array, billable?: boolean, note?: string, startAt?: string, endAt?: string or null, timeZone?: string, state?: “draft” / “confirmed” } yes

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { entry: { id: string, memberId: string, sessionId?: string or null, mentions?: array, version: integer, startAt: string, endAt: string or null, durationS: integer or null, description: string, recordId: string or null, projectRecordId: string or null, clientRecordId: string or null, tagIds: array, billable: boolean, note: string, timeZone: string, state: “draft” / “confirmed”, source: “timer” / “manual” / “import” / “agent” / “api”, deletedAt: string or null, invoicedAt: string or null }, changeId: integer }.

POST /track/mentions/{mentionId}/accept

Accept your invitation once and create your independently editable time entry.

Capability: track.entries.create. Kind: write.

Field In Type Required
mentionId path string yes

Output: { mentions: array, stoppedEntry?: { id: string, description: string } }.

POST /track/mentions/{mentionId}/decline

Decline your Track invitation.

Capability: track.entries.read. Kind: write.

Field In Type Required
mentionId path string yes

Output: { mentions: array, stoppedEntry?: { id: string, description: string } }.

GET /track/mentions/people

Return all eligible active colleague id/name pairs in this workspace. No paging. People only.

Capability: track.entries.update. Kind: read.

No input fields.

Output: { items: array }.

GET /track/pickers

Read permitted Boards clients and projects for Track pickers.

Capability: track.entries.read. Kind: read.

No input fields.

Output: { clients: array, projects: array }.

GET /track/preferences

Return your saved Track view and calendar range. No inputs or paging. People only.

Capability: track.entries.read. Kind: read.

No input fields.

Output: { view: “calendar” / “list” / “timesheet”, calendarRange: 1 or 5 or 7 or “month” }.

PATCH /track/preferences

Save your Track view and calendar range patch. Returns your saved preferences. People only.

Capability: track.entries.read. Kind: write.

Field In Type Required
Idempotency-Key header string yes
calendarRange body 1 or 5 or 7 or “month” no
view body “calendar” / “list” / “timesheet” no

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { view: “calendar” / “list” / “timesheet”, calendarRange: 1 or 5 or 7 or “month” }.

GET /track/settings

Read applicable Track settings. Other members’ rates and costs are excluded.

Capability: track.entries.read. Kind: read.

No input fields.

Output: { settings: { rates: array, rounding: array, reminders: object, weekStart: “monday” / “sunday”, tagBehaviour: object, tagOrder: array }, version: integer }.

PUT /track/settings

Save workspace Track settings at baseVersion. Returns settings and changeId. Human owner/admin only; stale versions fail.

Capability: track.settings.manage. Kind: write.

Field In Type Required
Idempotency-Key header string yes
baseVersion body integer yes
settings body { rates: array, rounding: array, reminders: { daily: boolean, time: string, idle: boolean, idleMinutes: integer, longTimer: boolean }, weekStart: “monday” / “sunday”, tagBehaviour: object, tagOrder: array } yes

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { settings: { rates: array, rounding: array, reminders: object, weekStart: “monday” / “sunday”, tagBehaviour: object, tagOrder: array }, version: integer, changeId: integer }.

POST /track/tags/{tagId}/archive

Set tagId archived state without changing historical entries. Returns tag and changeId. Human owner/admin only.

Capability: track.settings.manage. Kind: write.

Field In Type Required
tagId path string yes
Idempotency-Key header string yes
archived body boolean no
baseVersion body integer yes

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { tag: { id: string, name: string, color: “gray” / “red” / “orange” / “amber” / “green” / “teal” / “cyan” / “sky” / “blue” / “indigo” / “purple” / “pink”, archived: boolean, version: integer }, changeId: integer }.

POST /track/tags

Create a Track tag from name and palette color. Returns tag and changeId. Human owner/admin only.

Capability: track.settings.manage. Kind: write.

Field In Type Required
Idempotency-Key header string yes
color body “gray” / “red” / “orange” / “amber” / “green” / “teal” / “cyan” / “sky” / “blue” / “indigo” / “purple” / “pink” no
id body string no
name body string yes

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { tag: { id: string, name: string, color: “gray” / “red” / “orange” / “amber” / “green” / “teal” / “cyan” / “sky” / “blue” / “indigo” / “purple” / “pink”, archived: boolean, version: integer }, changeId: integer }.

GET /track/tags

List the Track tag catalogue, including archived tags for history.

Capability: track.entries.read. Kind: read.

No input fields.

Output: { items: array }.

PATCH /track/tags/{tagId}

Update tagId name and optional palette color. Returns tag and changeId. Human owner/admin only.

Capability: track.settings.manage. Kind: write.

Field In Type Required
tagId path string yes
Idempotency-Key header string yes
baseVersion body integer yes
color body “gray” / “red” / “orange” / “amber” / “green” / “teal” / “cyan” / “sky” / “blue” / “indigo” / “purple” / “pink” no
name body string yes

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { tag: { id: string, name: string, color: “gray” / “red” / “orange” / “amber” / “green” / “teal” / “cyan” / “sky” / “blue” / “indigo” / “purple” / “pink”, archived: boolean, version: integer }, changeId: integer }.

POST /track/timer/continue

Stop your running timer and continue entryId atomically. Returns the current entry and stoppedEntry. People only.

Capability: track.timer.use. Kind: write.

Field In Type Required
Idempotency-Key header string yes
entryId body string yes

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { entry: { id: string, memberId: string, sessionId?: string or null, mentions?: array, version: integer, startAt: string, endAt: string or null, durationS: integer or null, description: string, recordId: string or null, projectRecordId: string or null, clientRecordId: string or null, tagIds: array, billable: boolean, note: string, timeZone: string, state: “draft” / “confirmed”, source: “timer” / “manual” / “import” / “agent” / “api”, deletedAt: string or null, invoicedAt: string or null }, changeId: integer }.

GET /track/timer

Read your running timer, or null when none is running.

Capability: track.timer.use. Kind: read.

No input fields.

Output: { entry: { id: string, memberId: string, sessionId?: string or null, mentions?: array, version: integer, startAt: string, endAt: string or null, durationS: integer or null, description: string, recordId: string or null, projectRecordId: string or null, clientRecordId: string or null, tagIds: array, billable: boolean, note: string, timeZone: string, state: “draft” / “confirmed”, source: “timer” / “manual” / “import” / “agent” / “api”, deletedAt: string or null, invoicedAt: string or null } or null }.

POST /track/timer/start

Start a timer for yourself (agents start it for their person, as a draft).

Capability: track.timer.use. Kind: write.

Field In Type Required
Idempotency-Key header string yes
billable body boolean no
clientRecordId body string or null no
description body string no
id body string no
mentionedMemberIds body array no
note body string no
projectRecordId body string or null no
recordId body string no
startAt body string no
tagIds body array no
timeZone body string no

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { entry: { id: string, memberId: string, sessionId?: string or null, mentions?: array, version: integer, startAt: string, endAt: string or null, durationS: integer or null, description: string, recordId: string or null, projectRecordId: string or null, clientRecordId: string or null, tagIds: array, billable: boolean, note: string, timeZone: string, state: “draft” / “confirmed”, source: “timer” / “manual” / “import” / “agent” / “api”, deletedAt: string or null, invoicedAt: string or null }, changeId: integer }.

POST /track/timer/stop

Stop your running timer.

Capability: track.timer.use. Kind: write.

Field In Type Required
Idempotency-Key header string no
baseVersion body integer no
endAt body string no
entryId body string no

Idempotency-Key: Retry-safe key (8–128 chars). Replays return the stored result for 24 h.

Output: { entry: { id: string, memberId: string, sessionId?: string or null, mentions?: array, version: integer, startAt: string, endAt: string or null, durationS: integer or null, description: string, recordId: string or null, projectRecordId: string or null, clientRecordId: string or null, tagIds: array, billable: boolean, note: string, timeZone: string, state: “draft” / “confirmed”, source: “timer” / “manual” / “import” / “agent” / “api”, deletedAt: string or null, invoicedAt: string or null }, changeId: integer }.