Saaslivery API
/totps
Disable 2FA
password
string · min length: 1
propertyName
anything
/totps
/totps
Verify code and enable 2FA
code
string · min length: 6 · max length: 6
propertyName
anything
/totps
/ai/commands
Ask about the current app
POST /ai/commands — answer a question about the app the member is in.
app
string · min length: 1 · max length: 64
q
string · min length: 1 · max length: 2000
propertyName
anything
/ai/commands
/api-keys
Create API key
POST /api-keys: mint a key; the secret appears in this response only. A scoped key may start with an empty grant list: like a fresh role, it holds nothing until permissions are ticked on its detail page.
name
string · min length: 1 · max length: 100
full_access
scopes
array
expires_at
string · max length: 40
propertyName
anything
/api-keys
/api-keys/:key_id
Update or revoke API key
PUT /api-keys/:key_id: rename, re-scope, or revoke a key.
key_id
string · path
name
string · min length: 1 · max length: 100
full_access
scopes
array
status
expires_at
string · max length: 40
never_expires
propertyName
anything
/api-keys/example
/api-keys/:key_id/secret
Rotate API key secret
PUT /api-keys/:key_id/secret: replace the secret; old one dies now.
key_id
string · path
expires_at
string · max length: 40
never_expires
propertyName
anything
/api-keys/example/secret
/ats/jobs/:job_id/status
Move a job between draft, approval, open, hold and closed
job_id
string · path
status
reason
string · max length: 1000
propertyName
anything
/ats/jobs/example/status
/ats/stages/:stage_id/position
Reorder a stage
stage_id
string · path
position
integer · min: 0 · max: 999
propertyName
anything
/ats/stages/example/position
/ats/applications/:application_id/stage
Move an application to another stage
application_id
string · path
stage_id
string · min length: 1 · max length: 100
note
string · max length: 2000
propertyName
anything
/ats/applications/example/stage
/ats/applications/:application_id/status
Reject, hire, hold, withdraw or reopen an application
application_id
string · path
status
rejection_reason
string · max length: 1000
notify_candidate
template_id
string · max length: 100
propertyName
anything
/ats/applications/example/status
/ats/interviews/:interview_id/schedule
Put an interview on the calendar, or move it
interview_id
string · path
scheduled_at
string · min length: 1 · max length: 40
duration_minutes
integer · min: 5 · max: 600
location
string · max length: 500
instructions
string · max length: 5000
propertyName
anything
/ats/interviews/example/schedule
/ats/offers/:offer_id/status
Move an offer between draft, approval, approved, sent and rescinded
offer_id
string · path
status
reason
string · max length: 1000
propertyName
anything
/ats/offers/example/status
/ats/jobs
Create a job
title
string · min length: 1 · max length: 200
pipeline_id
string · max length: 100
description
string · max length: 50000
department_mrn
string · max length: 200
location
string · max length: 200
workplace_type
employment_type
headcount
integer · min: 1 · max: 999
hiring_manager_mrn
string · max length: 200
recruiter_mrn
string · max length: 200
hiring_team
array
approvals
array
salary_min
number
salary_max
number
salary_currency
string · max length: 3
salary_visible
screening_questions
array
careers_visibility
assessment_ref
string · max length: 100
propertyName
anything
/ats/jobs
/ats/jobs/:job_id/approvals
Record an approval decision on a job
job_id
string · path
status
comment
string · max length: 1000
propertyName
anything
/ats/jobs/example/approvals
/ats/pipelines
Create a pipeline
name
string · min length: 1 · max length: 100
description
string · max length: 1000
is_default
propertyName
anything
/ats/pipelines
/ats/pipelines/:pipeline_id/stages
Add a stage to a pipeline
pipeline_id
string · path
name
string · min length: 1 · max length: 100
type
key
string · max length: 50
position
integer · min: 0 · max: 999
criteria
array
questions
array
default_interviewers
array
required_evaluations
integer · min: 0 · max: 20
sla_days
integer · min: 0 · max: 365
duration_minutes
integer · min: 0 · max: 600
propertyName
anything
/ats/pipelines/example/stages
/ats/candidates
Create a candidate
name
string · min length: 1 · max length: 200
email
string · max length: 320 · email
phone
string · max length: 50
location
string · max length: 200
headline
string · max length: 200
links
object
linkedin
string · max length: 500
portfolio
string · max length: 500
github
string · max length: 500
tags
array
source
source_detail
string · max length: 200
referrer_mrn
string · max length: 200
owner_mrn
string · max length: 200
resume
array
propertyName
anything
/ats/candidates
/ats/candidates/:candidate_id/tags
Tag a candidate
candidate_id
string · path
tag
string · min length: 1 · max length: 50
propertyName
anything
/ats/candidates/example/tags
/ats/candidates/:candidate_id/activities
Add a note to a candidate's timeline
candidate_id
string · path
content
string · min length: 1 · max length: 20000
application_id
string · max length: 100
propertyName
anything
/ats/candidates/example/activities
/ats/candidates/:candidate_id/messages
Email a candidate from the careers mailbox
candidate_id
string · path
template_id
string · max length: 100
subject
string · max length: 300
body_html
string · max length: 50000
application_id
string · max length: 100
propertyName
anything
/ats/candidates/example/messages
/ats/applications
Put a candidate against a job
candidate_id
string · min length: 1 · max length: 100
job_id
string · min length: 1 · max length: 100
stage_id
string · max length: 100
source
propertyName
anything
/ats/applications
/ats/applications/:application_id/interviews
Request or schedule an interview
application_id
string · path
stage_id
string · max length: 100
title
string · max length: 200
panel
array
scheduled_at
string · max length: 40
duration_minutes
integer · min: 0 · max: 600
location
string · max length: 500
instructions
string · max length: 5000
propertyName
anything
/ats/applications/example/interviews
/ats/interviews/:interview_id/self-schedule
Offer the candidate slots to pick from
Offer the candidate a set of slots and hand back the link to send them. The token is the only credential on the open path, so it is minted fresh every time this is called: re-offering slots invalidates the previous link rather than leaving two live doors onto the same interview.
interview_id
string · path
slots
array
slot_1
string · max length: 40
slot_2
string · max length: 40
slot_3
string · max length: 40
slot_4
string · max length: 40
slot_5
string · max length: 40
duration_minutes
integer · min: 5 · max: 600
expires_at
string · max length: 40
location
string · max length: 500
instructions
string · max length: 5000
propertyName
anything
/ats/interviews/example/self-schedule
/ats/applications/:application_id/evaluations
Ask a member for a scorecard
application_id
string · path
evaluator_mrn
string · min length: 1 · max length: 200
stage_id
string · max length: 100
interview_id
string · max length: 100
is_shadow
propertyName
anything
/ats/applications/example/evaluations
/ats/applications/:application_id/offers
Draft an offer
application_id
string · path
package
object
base
number
currency
string · max length: 3
period
bonus
number
equity
string · max length: 200
benefits
array
notes
string · max length: 5000
start_date
string · max length: 10
expires_at
string · max length: 40
template_id
string · max length: 100
approvals
array
propertyName
anything
/ats/applications/example/offers
/ats/offers/:offer_id/approvals
Record an approval decision on an offer
Record one approver's decision. The last approval is what approves the offer, exactly as a job requisition's chain works.
offer_id
string · path
status
comment
string · max length: 1000
propertyName
anything
/ats/offers/example/approvals
/ats/templates
Create a template
kind
name
string · min length: 1 · max length: 100
subject
string · max length: 300
body
string · max length: 50000
config
object
sign_template_id
string · max length: 100
is_default
propertyName
anything
/ats/templates
/ats/settings/embeds
Create a careers embed
POST /ats/settings/embeds: mint a named embed for one website.
name
string · min length: 1 · max length: 120
enabled
allowed_origins
array
filters
object
layout
show_search
heading
string · max length: 120
propertyName
anything
/ats/settings/embeds
/ats/jobs/:job_id
Update a job
job_id
string · path
title
string · min length: 1 · max length: 200
pipeline_id
string · min length: 1 · max length: 100
description
string · max length: 50000
department_mrn
string · max length: 200
location
string · max length: 200
workplace_type
employment_type
headcount
integer · min: 1 · max: 999
hiring_manager_mrn
string · max length: 200
recruiter_mrn
string · max length: 200
hiring_team
array
approvals
array
salary_min
number
salary_max
number
salary_currency
string · max length: 3
salary_visible
screening_questions
array
careers_visibility
assessment_ref
string · max length: 100
propertyName
anything
/ats/jobs/example
/ats/pipelines/:pipeline_id
Update a pipeline
pipeline_id
string · path
name
string · min length: 1 · max length: 100
description
string · max length: 1000
is_default
status
propertyName
anything
/ats/pipelines/example
/ats/stages/:stage_id
Update a stage
stage_id
string · path
name
string · min length: 1 · max length: 100
type
key
string · max length: 50
criteria
array
questions
array
default_interviewers
array
required_evaluations
integer · min: 0 · max: 20
sla_days
integer · min: 0 · max: 365
duration_minutes
integer · min: 0 · max: 600
propertyName
anything
/ats/stages/example
/ats/candidates/:candidate_id
Update a candidate
candidate_id
string · path
name
string · min length: 1 · max length: 200
email
string · max length: 320 · email
phone
string · max length: 50
location
string · max length: 200
headline
string · max length: 200
links
object
linkedin
string · max length: 500
portfolio
string · max length: 500
github
string · max length: 500
tags
array
source
source_detail
string · max length: 200
referrer_mrn
string · max length: 200
owner_mrn
string · max length: 200
is_archived
resume
array
propertyName
anything
/ats/candidates/example
/ats/interviews/:interview_id
Update an interview and its panel
interview_id
string · path
title
string · max length: 200
stage_id
string · max length: 100
panel
array
duration_minutes
integer · min: 0 · max: 600
location
string · max length: 500
instructions
string · max length: 5000
status
propertyName
anything
/ats/interviews/example
/ats/evaluations/:evaluation_id
Submit a scorecard
Submit a scorecard: scores keyed to the stage's criteria, then the application's rating and progress recomputed from every submitted card.
evaluation_id
string · path
rating
integer · min: 1 · max: 5
recommendation
scores
question_responses
array
strengths
string · max length: 2000
concerns
string · max length: 2000
notes
string · max length: 5000
propertyName
anything
/ats/evaluations/example
/ats/offers/:offer_id
Update a draft offer
offer_id
string · path
package
object
base
number
currency
string · max length: 3
period
bonus
number
equity
string · max length: 200
benefits
array
notes
string · max length: 5000
start_date
string · max length: 10
expires_at
string · max length: 40
template_id
string · max length: 100
approvals
array
propertyName
anything
/ats/offers/example
/ats/templates/:template_id
Update a template
template_id
string · path
name
string · min length: 1 · max length: 100
subject
string · max length: 300
body
string · max length: 50000
config
object
sign_template_id
string · max length: 100
is_default
status
propertyName
anything
/ats/templates/example
/ats/settings/embeds/:embed_id
Update a careers embed
PUT /ats/settings/embeds/:embed_id: rename, retarget or switch it off. The stored embed is the base and the body is laid over it, so a page that saves one control at a time never clears the others.
embed_id
string · path
name
string · min length: 1 · max length: 120
enabled
allowed_origins
array
filters
object
layout
show_search
heading
string · max length: 120
propertyName
anything
/ats/settings/embeds/example
/me/notification-preferences
Patch notification prefs
channel
patch
object
propertyName
anything
/me/notification-preferences
/push-subscriptions
Turn on notifications for this browser
POST /push-subscriptions: this browser may now show notifications for the signed-in person.
endpoint
string · min length: 10 · max length: 2000
keys
object
propertyName
anything
/push-subscriptions
/push-devices
Turn on notifications for this phone
POST /push-devices: this phone may now show notifications for the signed-in person.
token
string · min length: 20 · max length: 4096
platform
propertyName
anything
/push-devices
/finance/accounts
Create an account
code
string · min length: 1 · max length: 20
name
string · min length: 1 · max length: 200
type
parent_id
string
description
string · max length: 1000
normal_balance
is_contra
is_bank
propertyName
anything
/finance/accounts
/finance/accounts/:account_id
Update an account
account_id
string · path
display_name
string · max length: 200
show_in_unified
propertyName
anything
/finance/accounts/example
/activity
undocumented /activity
/activity
/admin/file-members/:member_mrn/folders
undocumented /admin/file-members/:member_mrn/folders
member_mrn
string · path
/admin/file-members/example/folders
/admin/file-members/:member_mrn/files
undocumented /admin/file-members/:member_mrn/files
member_mrn
string · path
/admin/file-members/example/files
/admin/file-stats
undocumented /admin/file-stats
GET /admin/file-stats — workspace storage overview for the admin view.
/admin/file-stats
/admin/activity-exports
undocumented /admin/activity-exports
GET /admin/activity-exports — the audit trail as a CSV download. Optional ``after`` / ``before`` ISO instants bound the window.
/admin/activity-exports
/admin/file-transfers
Transfer file ownership
POST /admin/file-transfers — move every file and folder one member owns to another member (offboarding). Root-level name collisions in the recipient's space are suffixed, never merged or replaced.
from_mrn
string · min length: 1
to_mrn
string · min length: 1
propertyName
anything
/admin/file-transfers
/elevations
Break glass into admin mode
POST /elevations — break glass. Re-authentication is the point of the exercise: a stolen session should not be able to elevate itself just because the person it was stolen from happens to be an admin. TOTP when the account has it (a second factor beats a password an attacker may already have), password otherwise, and a recovery code as the way back in for someone who lost their phone. Deliberately never a mailed code: admin actions must not depend on reaching a mailbox, least of all one we host.
reason
string · min length: 3 · max length: 500
code
string · min length: 6 · max length: 6
totp
string · min length: 6 · max length: 10
propertyName
anything
/elevations
/admin-audit
undocumented /admin-audit
GET /admin-audit: what admins did while elevated, newest first. Reads coalesce, so one row can stand for many identical views; `hits` says how many.
/admin-audit
/api-keys/:key_id
undocumented /api-keys/:key_id
DELETE /api-keys/:key_id: remove the key and its audit row.
key_id
string · path
/api-keys/example
/api-keys
undocumented /api-keys
GET /api-keys: list the workspace's API keys (never the secrets).
/api-keys
/applications/:slug/status
undocumented /applications/:slug/status
GET /accounts/apps/status/:slug — Check install status for a specific app.
slug
string · path
/applications/example/status
/applications/:slug/requests
undocumented /applications/:slug/requests
POST /applications/:slug/requests — Request app install (any authenticated member).
slug
string · path
/applications/example/requests
/apps/:slug/access
undocumented /apps/:slug/access
GET /apps/:slug/access — everything configured for one app, in one envelope: tile access, permission matrix, config document, and exception grants. The audit surface for "who can see what in this app".
slug
string · path
/apps/example/access
/apps/:slug/settings
undocumented /apps/:slug/settings
GET /apps/:slug/settings — the app's effective config document.
slug
string · path
/apps/example/settings
/applications/:slug/installations
Install app
POST /accounts/apps/install — Install an app (admin/owner only).
slug
string · path
access_policy
allowed_roles
array
propertyName
anything
/applications/example/installations
/applications/:slug/access-requests
Request access to restricted app
POST /apps/:slug/access-requests — Request access to a restricted app. Notifies all workspace admins (owner + admin roles). Mirrors the install- request flow (api_request_install) but for apps that ARE installed yet gated by access_policy='roles' the requester doesn't hold.
slug
string · path
message
string · max length: 280
propertyName
anything
/applications/example/access-requests
/applications/:slug/access
Set app access policy
Update which roles can reach an installed app. Body: {access_policy: "everyone"|"roles"|"approval", allowed_roles?: [role_id]} When access_policy is 'everyone' the allowed_roles list is cleared.
slug
string · path
access_policy
allowed_roles
array
redlist
array
propertyName
anything
/applications/example/access
/apps/:slug/roles/:role_id/permissions
Set one app's permission slice on a role
PUT /apps/:slug/roles/:role_id/permissions — replace ONE app's slice of a role's permissions. The only role-editing power an app admin has: other apps' slices, platform roles, and role membership are out of reach.
slug
string · path
role_id
string · path
permissions
array
propertyName
anything
/apps/example/roles/example/permissions
/apps/:slug/settings
undocumented /apps/:slug/settings
PUT /apps/:slug/settings — replace the app's config document. The body is the full document. It is validated against the pytastic schema the app registered via core.appconfig (rule 12's schema-first requirement is satisfied per-app; a static route schema is impossible for a surface whose shape each app defines).
slug
string · path
/apps/example/settings
/ats/jobs/:job_id
undocumented /ats/jobs/:job_id
job_id
string · path
/ats/jobs/example
/ats/pipelines/:pipeline_id
undocumented /ats/pipelines/:pipeline_id
pipeline_id
string · path
/ats/pipelines/example
/ats/stages/:stage_id
undocumented /ats/stages/:stage_id
stage_id
string · path
/ats/stages/example
/ats/candidates/:candidate_id/tags/:tag
undocumented /ats/candidates/:candidate_id/tags/:tag
candidate_id
string · path
tag
string · path
/ats/candidates/example/tags/example
/ats/applications/:application_id
undocumented /ats/applications/:application_id
application_id
string · path
/ats/applications/example
/ats/interviews/:interview_id
undocumented /ats/interviews/:interview_id
Cancel an interview. The calendar entry is cancelled, not deleted, so it stays visible struck through in everyone's week instead of vanishing.
interview_id
string · path
/ats/interviews/example
/ats/evaluations/:evaluation_id
undocumented /ats/evaluations/:evaluation_id
Cancel a scorecard, which is how an interviewer declines and how a recruiter takes a request back. A submitted one is left alone: the record of what someone thought is not deletable.
evaluation_id
string · path
/ats/evaluations/example
/ats/templates/:template_id
undocumented /ats/templates/:template_id
template_id
string · path
/ats/templates/example
/ats/settings/embeds/:embed_id
undocumented /ats/settings/embeds/:embed_id
DELETE /ats/settings/embeds/:embed_id: retire a snippet for good.
embed_id
string · path
/ats/settings/embeds/example
/ats/jobs
undocumented /ats/jobs
/ats/jobs
/ats/jobs/:job_id
undocumented /ats/jobs/:job_id
job_id
string · path
/ats/jobs/example
/ats/jobs/:job_id/matches
undocumented /ats/jobs/:job_id/matches
Candidates ranked against this job's own text, nearest first. Deliberately not offered to a grant-scoped caller: the authz chain takes ats.candidates.view, because a ranking computed over a subset of the pool still reads like a shortlist and would be wrong in a way nobody could see.
job_id
string · path
/ats/jobs/example/matches
/ats/pipelines
undocumented /ats/pipelines
/ats/pipelines
/ats/pipelines/:pipeline_id
undocumented /ats/pipelines/:pipeline_id
pipeline_id
string · path
/ats/pipelines/example
/ats/pipelines/:pipeline_id/stages
undocumented /ats/pipelines/:pipeline_id/stages
pipeline_id
string · path
/ats/pipelines/example/stages
/ats/candidates
undocumented /ats/candidates
/ats/candidates
/ats/candidates/:candidate_id
undocumented /ats/candidates/:candidate_id
candidate_id
string · path
/ats/candidates/example
/ats/candidates/:candidate_id/activities
undocumented /ats/candidates/:candidate_id/activities
candidate_id
string · path
/ats/candidates/example/activities
/ats/candidates/:candidate_id/resume
undocumented /ats/candidates/:candidate_id/resume
candidate_id
string · path
/ats/candidates/example/resume
/ats/candidates/:candidate_id/messages
undocumented /ats/candidates/:candidate_id/messages
candidate_id
string · path
/ats/candidates/example/messages
/ats/applications
undocumented /ats/applications
/ats/applications
/ats/applications/:application_id
undocumented /ats/applications/:application_id
application_id
string · path
/ats/applications/example
/ats/applications/:application_id/summary
undocumented /ats/applications/:application_id/summary
What the panel said, read back in a paragraph. The model is handed exactly the scorecards this caller may read, through the same redaction the list endpoint applies, so a summary can never be the back door through which a peer's opinion anchors someone who has not written their own yet. Nothing is stored: it is computed on demand.
application_id
string · path
/ats/applications/example/summary
/ats/applications/:application_id/interviews
undocumented /ats/applications/:application_id/interviews
application_id
string · path
/ats/applications/example/interviews
/ats/evaluations/mine
undocumented /ats/evaluations/mine
The caller's own scorecard queue, pending first. The surface a member who is only ever an interviewer sees, so it needs no ATS permission at all: it only ever returns rows addressed to them.
/ats/evaluations/mine
/ats/applications/:application_id/evaluations
undocumented /ats/applications/:application_id/evaluations
Every scorecard on an application, anti-anchored in the query.
application_id
string · path
/ats/applications/example/evaluations
/ats/evaluations/:evaluation_id
undocumented /ats/evaluations/:evaluation_id
evaluation_id
string · path
/ats/evaluations/example
/ats/applications/:application_id/offers
undocumented /ats/applications/:application_id/offers
application_id
string · path
/ats/applications/example/offers
/ats/offers/:offer_id
undocumented /ats/offers/:offer_id
offer_id
string · path
/ats/offers/example
/ats/templates
undocumented /ats/templates
/ats/templates
/ats/templates/:template_id
undocumented /ats/templates/:template_id
template_id
string · path
/ats/templates/example
/ats/templates/:template_id/preview
undocumented /ats/templates/:template_id/preview
What this template says about this candidate, without sending it.
template_id
string · path
/ats/templates/example/preview
/ats/reports/:report_key
undocumented /ats/reports/:report_key
One report, named by ``report_key``. Authorization ran in authz.py.
report_key
string · path
/ats/reports/example
/ats/settings/mailboxes
undocumented /ats/settings/mailboxes
GET /ats/settings/mailboxes: what the careers picker may offer, and what not. Every active hosted mailbox, shared groups labelled by name. A refused row is returned DISABLED with its reason, never omitted: a mailbox missing from the list reads as a mailbox that does not exist, and somebody goes looking for it in Mail. A hosted mailbox is on a domain the workspace owns, so the refusal should never fire; it asks anyway, because a rule with an exception is a rule somebody routes around.
/ats/settings/mailboxes
/ats/settings/embeds/:embed_id/rotate-key
undocumented /ats/settings/embeds/:embed_id/rotate-key
POST /ats/settings/embeds/:embed_id/rotate-key: kill the old snippet. The old key stops resolving immediately and answers the unavailable frame, which is the same thing an unknown key gets: a rotation must not leave a 404 behind that tells an attacker which keys once existed.
embed_id
string · path
/ats/settings/embeds/example/rotate-key
/attendance/locations/:id
undocumented /attendance/locations/:id
Permanently delete a location. Workers assigned to it must be reassigned first (the Workers app handles that via its own reassignment endpoint, driven by the delete dialog). Here we just remove the row and emit .deleted so projections drop their copy.
id
string · path
/attendance/locations/example
/attendance/status
undocumented /attendance/status
/attendance/status
/attendance/entries
undocumented /attendance/entries
/attendance/entries
/attendance/timesheets
undocumented /attendance/timesheets
/attendance/timesheets
/attendance/timesheets/:id
undocumented /attendance/timesheets/:id
id
string · path
/attendance/timesheets/example
/attendance/timezones
undocumented /attendance/timezones
Friendly timezone search for the location form's picker. Searchable by city, US state, country, or zone (e.g. "houston", "texas", "port louis"). Returns {timezone, label}; the picker stores the IANA value and shows the label. Reference data only — no workspace scoping needed, but still requires an authenticated session. See core/timezones.py.
/attendance/timezones
/attendance/locations
undocumented /attendance/locations
/attendance/locations
/attendance/timesheets/:id
Update a timesheet
id
string · path
status
string · min length: 1 · max length: 20
propertyName
anything
/attendance/timesheets/example
/attendance/locations/:id
Update a location
id
string · path
name
string · min length: 1 · max length: 120
timezone
string · min length: 1 · max length: 64
workdays
work_start
string · max length: 5
work_end
string · max length: 5
is_default
propertyName
anything
/attendance/locations/example
/attendance/clock-ins
Clock in
note
string · max length: 500
source
string · max length: 50
propertyName
anything
/attendance/clock-ins
/attendance/clock-outs
Clock out
note
string · max length: 500
propertyName
anything
/attendance/clock-outs
/attendance/pings
Record where a clocked-in device has been
Record a device's whereabouts on the caller's open session. A ping inside the resume window reopens a session the dropped socket closed.
pings
array
propertyName
anything
/attendance/pings
/attendance/locations
Create a location
name
string · min length: 1 · max length: 120
timezone
string · min length: 1 · max length: 64
workdays
work_start
string · max length: 5
work_end
string · max length: 5
is_default
propertyName
anything
/attendance/locations
/sessions/links
Email a sign-in link
POST /sessions/links — mail proof of mailbox for one workspace. Always answers the same way. Whether the address exists, belongs to this workspace, or is a stranger's is not something an unauthenticated caller gets to learn: this endpoint would otherwise be a membership oracle for any workspace whose slug you can guess.
email
string · min length: 1 · email
workspace
string · min length: 1 · max length: 100
propertyName
anything
/sessions/links
/sessions
Sign in
POST /sessions — sign in. Three ways in, all landing on the same seat lookup and 2FA gate: * a password (`email` + `password` + `workspace`), * a confirmed link (`token`), * the fast path (`email` + `workspace`) for a caller already holding a live session for that identity, which mints and mails nothing. Whichever route, 2FA is asked for exactly once at the end, and only if the account has it. There is no mailed code: see core/magiclink.py for why.
email
string · min length: 1 · email
workspace
string · min length: 1 · max length: 100
password
string · min length: 1
token
string · min length: 1 · max length: 200
totp
string · min length: 6 · max length: 8
is_recovery_code
propertyName
anything
/sessions
/workspaces/lookup
Find a workspace by name
POST /workspaces/lookup — resolve a typed workspace name to its address. Unlike the sign-in endpoints this one DOES confirm existence, because a finder that refuses to say whether it found anything is not a finder. The exposure is small: a workspace slug is already its public subdomain, so this tells an enumerator nothing the DNS name does not. Rate limited by IP to keep that from being cheap at scale.
slug
string · min length: 1 · max length: 100
propertyName
anything
/workspaces/lookup
/workspaces
Sign up
company_name
string · min length: 1 · max length: 200
full_name
string · min length: 1 · max length: 200
email
string · min length: 1 · email
terms_agreed
company_location
string
industry
string
company_size
string
job_title
string
propertyName
anything
/workspaces
/verifications
Verify OTP
code
string · min length: 1
password
string · min length: 8
propertyName
anything
/verifications
/invitations/:token
Accept invitation
PUT /invitations/:token — Accept a workspace invitation and set a password. Acceptance flips the membership from "invited" to "joined", which is the gate `_seat` enforces on every sign-in afterwards. Holding the invitation mail already proves the mailbox, so the password chosen here is not a second proof: it is the credential for every sign-in after this one, so that getting in never depends on reaching a mailbox again.
token
string · path
password
string · min length: 8
totp
string · min length: 6 · max length: 8
propertyName
anything
/invitations/example
/password-resets/:token
Set a password through a mailed link
PUT /password-resets/:token: set a new password through a mailed link. Rotating the stamp burns the link and signs the account out everywhere.
token
string · path
password
string · min length: 8
propertyName
anything
/password-resets/example
/avatars/:member_id
undocumented /avatars/:member_id
DELETE /avatars/:member_id — clear avatar, revert to initials.
member_id
string · path
/avatars/example
/avatars/:member_id
undocumented /avatars/:member_id
POST /avatars/:member_id — upload profile avatar to R2.
member_id
string · path
/avatars/example
/payment-methods
Add payment method
POST /accounts/billing/payment-methods — Add a payment method via Flutterwave v4.
card_number
string · min length: 13 · max length: 19
expiry_month
string · min length: 1 · max length: 2
expiry_year
string · min length: 2 · max length: 4
cvv
string · min length: 3 · max length: 4
propertyName
anything
/payment-methods
/plan
Switch plan
PUT /plan: switch plan immediately, with upgrade proration.
plan
propertyName
anything
/plan
/plan/interval
Update billing interval
PUT /plan/interval — Switch billing interval (monthly/annual). The live invoice loop reads the interval fresh on its next firing, so no loop surgery is needed for annual→monthly. Switching an ACTIVE workspace TO annual bills the year upfront now: an immediate 'seats' invoice.due is emitted, and the existing monthly loop converts itself to the usage loop when it next fires.
billing_interval
propertyName
anything
/plan/interval
/finance/bills/:entry_id
Receive/approve/void a bill
entry_id
string · path
status
propertyName
anything
/finance/bills/example
/finance/bills
Create a bill
date
string · min length: 10
items
array
company_mrn
string
contact_mrn
string
currency
exchange_rate
number
due_date
string · min length: 10
memo
string · max length: 5000
tags
array
sources
array
adjustments
array
dimensions
idempotency_key
string · max length: 100
propertyName
anything
/finance/bills
/finance/bills/:entry_id
Update a draft bill
entry_id
string · path
date
string · min length: 10
items
array
company_mrn
string
contact_mrn
string
currency
exchange_rate
number
due_date
string · min length: 10
memo
string · max length: 5000
tags
array
adjustments
array
dimensions
propertyName
anything
/finance/bills/example
/boards/:board_id/tasks/:task_id
undocumented /boards/:board_id/tasks/:task_id
Return a single task from the board to the incubator.
board_id
string · path
task_id
string · path
/boards/example/tasks/example
/boards/:board_id/tasks
undocumented /boards/:board_id/tasks
DELETE /boards/:board_id/tasks?scheduled=false — clear unplanned tasks from board.
board_id
string · path
/boards/example/tasks
/boards/:board_id
Delete a board
board_id
string · path
confirm_key
string · min length: 1
propertyName
anything
/boards/example
/boards/:board_id/topics/:topic_id
undocumented /boards/:board_id/topics/:topic_id
DELETE /boards/:board_id/topics/:topic_id: remove a topic; its tasks keep going with no topic.
board_id
string · path
topic_id
string · path
/boards/example/topics/example
/boards/:board_id/members/:member_id
undocumented /boards/:board_id/members/:member_id
board_id
string · path
member_id
string · path
/boards/example/members/example
/boards
undocumented /boards
/boards
/boards/:board_id/task-filters
undocumented /boards/:board_id/task-filters
GET /boards/:board_id/task-filters: the fields a board's tasks can be filtered by.
board_id
string · path
/boards/example/task-filters
/boards/:board_id/task-filters/:key/options
undocumented /boards/:board_id/task-filters/:key/options
GET /boards/:board_id/task-filters/:key/options?q=...: one field's values on a board.
board_id
string · path
key
string · path
/boards/example/task-filters/example/options
/boards/:board_id/topics
undocumented /boards/:board_id/topics
GET /boards/:board_id/topics?q=...: a board's topics.
board_id
string · path
/boards/example/topics
/boards/:board_id/members
undocumented /boards/:board_id/members
board_id
string · path
/boards/example/members
/boards/:board_id/columns
Rename a board column
Rename a board column (lane) and update all tasks referencing it.
board_id
string · path
old_name
string · min length: 1
new_name
string · min length: 1
propertyName
anything
/boards/example/columns
/boards/:board_id/members/:member_id
Change a project member's role
board_id
string · path
member_id
string · path
role
propertyName
anything
/boards/example/members/example
/boards
Create a board
title
string · min length: 1 · max length: 200
description
string · max length: 2000
template_id
string
is_template
grid
object
propertyName
anything
/boards
/boards/:board_id/tasks
Pull tasks onto a board
POST /boards/:board_id/tasks — pull tasks from incubator onto a board. Accepts either explicit task_ids or a schedule_id, exactly one. With schedule_id, every incubator task in that schedule is pulled at once.
board_id
string · path
task_ids
array
schedule_id
string
propertyName
anything
/boards/example/tasks
/boards/:board_id/members
Add a project member
board_id
string · path
member_id
string · min length: 1
role
propertyName
anything
/boards/example/members
/views
Save a board view
board_id
string
name
string · min length: 1 · max length: 80
tab
string · min length: 1 · max length: 40
schedule_id
string
propertyName
anything
/views
/boards/:board_id
Update board settings
Update board settings (name, description, columns).
board_id
string · path
deleted
title
string · min length: 1 · max length: 200
description
string · max length: 2000
grid
object
propertyName
anything
/boards/example
/finance/budgets/:budget_id
Update a budget
budget_id
string · path
account_id
string · min length: 1
period_start
string · min length: 10
period_end
string · min length: 10
amount
number
dimensions
object
notes
string · max length: 2000
propertyName
anything
/finance/budgets/example
/finance/budgets
Create a budget
account_id
string · min length: 1
period_start
string · min length: 10
period_end
string · min length: 10
amount
number
dimensions
object
notes
string · max length: 2000
propertyName
anything
/finance/budgets
/calls/:id
undocumented /calls/:id
id
string · path
/calls/example
/calls/:id/participants/:member_mrn
undocumented /calls/:id/participants/:member_mrn
id
string · path
member_mrn
string · path
/calls/example/participants/example
/calls/:id/sessions
undocumented /calls/:id/sessions
id
string · path
/calls/example/sessions
/calls/:id/recordings/:recording_id
undocumented /calls/:id/recordings/:recording_id
id
string · path
recording_id
string · path
/calls/example/recordings/example
/calls
undocumented /calls
/calls
/calls/:id
undocumented /calls/:id
id
string · path
/calls/example
/calls/:id/participants
undocumented /calls/:id/participants
id
string · path
/calls/example/participants
/calls/:id/admission
undocumented /calls/:id/admission
Poll endpoint for a member who knocked under the lobby policy. Mirrors the guest admission poll. Returns one of: - {state: 'waiting'} — host hasn't decided yet - {state: 'denied'} — host declined - {state: 'admitted'} — host let them in; the member then navigates to the room, where api_join_call mints their LK token - {state: 'idle'} — no pending knock for this member
id
string · path
/calls/example/admission
/calls/:id/links
undocumented /calls/:id/links
id
string · path
/calls/example/links
/calls/:id/messages
undocumented /calls/:id/messages
id
string · path
/calls/example/messages
/calls/:id/recordings
undocumented /calls/:id/recordings
id
string · path
/calls/example/recordings
/calls/:id
Update a call
id
string · path
title
string · max length: 200
scheduled_at
string
status
format
access_policy
settings
object
attendees_can_mic
attendees_can_camera
attendees_can_screenshare
attendees_can_chat
hide_attendee_tiles
propertyName
anything
/calls/example
/calls
Create a call
type
mode
format
title
string · max length: 200
participants
array
source_mrn
string
scheduled_at
string
max_participants
integer · min: 2 · max: 200
access_policy
settings
object
external_invitees_text
string · max length: 4000
propertyName
anything
/calls
/calls/:id/sessions
undocumented /calls/:id/sessions
id
string · path
/calls/example/sessions
/calls/:id/sessions/leave
undocumented /calls/:id/sessions/leave
id
string · path
/calls/example/sessions/leave
/calls/:id/token
undocumented /calls/:id/token
Mint a fresh LiveKit token for a call the member is already in. Used by the client's proactive refresh timer before the current token's `exp` kicks in. No side effects — does not update participant status or emit events.
id
string · path
/calls/example/token
/calls/:id/recordings/:recording_id/parts
undocumented /calls/:id/recordings/:recording_id/parts
Receive one chunk of an in-progress recording and stream it into R2 as a multipart part. Binary multipart body (not JSON). Host-only. The server holds at most one part (~8 MiB) in memory, so even long recordings never balloon it.
id
string · path
recording_id
string · path
/calls/example/recordings/example/parts
/chats/:id/call-requests
Request a call from chat
POST /chats/:id/call-requests — ask the Calls app to start a call.
id
string · path
mode
propertyName
anything
/chats/example/call-requests
/canvas/boards/:board_id
undocumented /canvas/boards/:board_id
DELETE /canvas/boards/:board_id — soft-delete + drop grants (owner only).
board_id
string · path
/canvas/boards/example
/canvas/trash
undocumented /canvas/trash
DELETE /canvas/trash: delete for good every trashed board the caller may purge.
/canvas/trash
/canvas/trash/:board_id
undocumented /canvas/trash/:board_id
DELETE /canvas/trash/:board_id: delete a trashed board for good and free its storage now.
board_id
string · path
/canvas/trash/example
/canvas/boards/:board_id/comments/:comment_id
undocumented /canvas/boards/:board_id/comments/:comment_id
DELETE /canvas/boards/:board_id/comments/:comment_id — author or board manager.
board_id
string · path
comment_id
string · path
/canvas/boards/example/comments/example
/canvas/boards/:board_id/vote-sessions/:session_id/votes/:object_id
undocumented /canvas/boards/:board_id/vote-sessions/:session_id/votes/:object_id
DELETE /canvas/boards/:board_id/vote-sessions/:session_id/votes/:object_id. Takes back ONE of the caller's votes on that object (a session that allows repeats can hold several), and only ever their own.
board_id
string · path
session_id
string · path
object_id
string · path
/canvas/boards/example/vote-sessions/example/votes/example
/canvas/boards/:board_id/exports/:target
undocumented /canvas/boards/:board_id/exports/:target
DELETE /canvas/boards/:board_id/exports/:target — take this board's saved exports back out of Files. Files refuses to delete anything Canvas owns, so removing an export has to happen here, in the app that put it there.
board_id
string · path
target
string · path
/canvas/boards/example/exports/example
/canvas/boards
undocumented /canvas/boards
GET /canvas/boards — boards the caller can access. ?is_template=true filters templates.
/canvas/boards
/canvas/templates
undocumented /canvas/templates
GET /canvas/templates — sugar for ?is_template=true.
/canvas/templates
/canvas/boards/:board_id
undocumented /canvas/boards/:board_id
GET /canvas/boards/:board_id — board metadata (no content).
board_id
string · path
/canvas/boards/example
/canvas/trash
undocumented /canvas/trash
GET /canvas/trash: trashed boards the caller may restore or delete for good.
/canvas/trash
/canvas/boards/:board_id/content
undocumented /canvas/boards/:board_id/content
GET /canvas/boards/:board_id/content — opaque board content to bootstrap the client.
board_id
string · path
/canvas/boards/example/content
/canvas/boards/:board_id/comments
undocumented /canvas/boards/:board_id/comments
GET /canvas/boards/:board_id/comments — threaded comments for a board.
board_id
string · path
/canvas/boards/example/comments
/canvas/boards/:board_id/vote-sessions
undocumented /canvas/boards/:board_id/vote-sessions
GET /canvas/boards/:board_id/vote-sessions — history, newest first.
board_id
string · path
/canvas/boards/example/vote-sessions
/canvas/boards/:board_id/vote-sessions/:session_id
undocumented /canvas/boards/:board_id/vote-sessions/:session_id
GET /canvas/boards/:board_id/vote-sessions/:session_id — one session + counts.
board_id
string · path
session_id
string · path
/canvas/boards/example/vote-sessions/example
/canvas/boards/:board_id
Update a board
PATCH /canvas/boards/:board_id — title, description, grid settings.
board_id
string · path
deleted
title
string · min length: 1 · max length: 200
description
string · max length: 2000
grid
object
propertyName
anything
/canvas/boards/example
/canvas/boards/:board_id/content
Save board content
PATCH /canvas/boards/:board_id/content — persist the (debounced) content snapshot.
board_id
string · path
ydoc_state
string · min length: 1
thumbnail_key
string · max length: 512
restore_snapshot_id
string
asset_ids
array
propertyName
anything
/canvas/boards/example/content
/canvas/boards/:board_id/comments/:comment_id
Edit/resolve a comment
PATCH /canvas/boards/:board_id/comments/:comment_id — edit body (author) or resolve.
board_id
string · path
comment_id
string · path
body
string · min length: 1 · max length: 4000
resolved
propertyName
anything
/canvas/boards/example/comments/example
/canvas/boards/:board_id/vote-sessions/:session_id
Close a vote session
PATCH /canvas/boards/:board_id/vote-sessions/:session_id — close the round. Closing freezes the tally into `results` so history survives the board being edited afterwards, and stops badges reading from a session nobody is in.
board_id
string · path
session_id
string · path
status
object_labels
array
propertyName
anything
/canvas/boards/example/vote-sessions/example
/canvas/boards
Create a board
POST /canvas/boards — create a board (optionally cloned from a template).
title
string · min length: 1 · max length: 200
description
string · max length: 2000
template_id
string
is_template
grid
object
propertyName
anything
/canvas/boards
/canvas/boards/:board_id/duplications
undocumented /canvas/boards/:board_id/duplications
POST /canvas/boards/:board_id/duplications — copy a board (or instantiate a template).
board_id
string · path
/canvas/boards/example/duplications
/canvas/boards/:board_id/assets
Register a board image
POST /canvas/boards/:board_id/assets — register an uploaded board image. Called by the editor right after the platform upload confirm so the asset is servable immediately, instead of waiting on the upload-confirmed event round trip. The event handler in events.py remains the idempotent backup.
board_id
string · path
asset_id
string · min length: 6 · max length: 64
storage_key
string · min length: 1 · max length: 512
filename
string · min length: 1 · max length: 255
content_type
string · min length: 1 · max length: 100
size_bytes
integer · min: 0
width
integer · min: 0
height
integer · min: 0
propertyName
anything
/canvas/boards/example/assets
/canvas/boards/:board_id/comments
Add a comment
POST /canvas/boards/:board_id/comments — add a comment.
board_id
string · path
body
string · min length: 1 · max length: 4000
object_id
string · max length: 64
parent_id
string · max length: 64
nx
number
ny
number
propertyName
anything
/canvas/boards/example/comments
/canvas/boards/:board_id/vote-sessions
Start a vote session
POST /canvas/boards/:board_id/vote-sessions — open a round of dot voting.
board_id
string · path
label
string · max length: 120
max_votes_per_member
integer · min: 1 · max: 99
allow_repeat_votes
scope_frame_id
string · max length: 64
scope_ids
array
propertyName
anything
/canvas/boards/example/vote-sessions
/canvas/boards/:board_id/vote-sessions/:session_id/votes
Cast a vote
POST /canvas/boards/:board_id/vote-sessions/:session_id/votes — spend one vote.
board_id
string · path
session_id
string · path
object_id
string · min length: 1 · max length: 64
propertyName
anything
/canvas/boards/example/vote-sessions/example/votes
/canvas/boards/:board_id/exports
Export a board
POST /canvas/boards/:board_id/exports — download is client-side; target=files persists the client-rendered image to R2 and emits an event Files ingests.
board_id
string · path
format
target
data_url
string · min length: 1
filename
string · max length: 200
propertyName
anything
/canvas/boards/example/exports
/chats/:id
Update a chat
PATCH /chats/:id — update group name, description, or avatar.
id
string · path
name
string · max length: 100
description
string · max length: 500
avatar_key
string
propertyName
anything
/chats/example
/chats
Create a chat
POST /chats — create a conversation.
type
name
string · min length: 1 · max length: 100
description
string · max length: 500
participants
array
propertyName
anything
/chats
/chats/:id
undocumented /chats/:id
DELETE /chats/:id — delete a conversation. For a DM this is per-member: it clears the chat from the caller's own view only, leaving the other participant's copy and history intact. The chat reappears for them if a new message arrives, showing only the post-delete history. For a group it removes the conversation for everyone, so it needs the in-chat admin role or the workspace-wide manage override.
id
string · path
/chats/example
/chats/:id/messages
undocumented /chats/:id/messages
DELETE /chats/:id/messages — clear the conversation for the caller only.
id
string · path
/chats/example/messages
/chats/:id/messages/:msg_id
undocumented /chats/:id/messages/:msg_id
DELETE /chats/:id/messages/:msg_id — soft-delete a message.
id
string · path
msg_id
string · path
/chats/example/messages/example
/chats/:id/messages/:msg_id/reactions/:emoji
undocumented /chats/:id/messages/:msg_id/reactions/:emoji
DELETE /chats/:id/messages/:msg_id/reactions/:emoji — remove a reaction.
id
string · path
msg_id
string · path
emoji
string · path
/chats/example/messages/example/reactions/example
/chats/:id/participants/:member_mrn
undocumented /chats/:id/participants/:member_mrn
DELETE /chats/:id/participants/:member_mrn — remove from a group, or leave.
id
string · path
member_mrn
string · path
/chats/example/participants/example
/chats/lists/:list_id
undocumented /chats/lists/:list_id
DELETE /chats/lists/:list_id — delete a personal list. chat_list_items.list_id cascades, so memberships go with it instead of lingering as tags pointing at a list that no longer exists.
list_id
string · path
/chats/lists/example
/chats/:id/favourite
undocumented /chats/:id/favourite
DELETE /chats/:id/favourite — remove the favourite mark (per-user).
id
string · path
/chats/example/favourite
/chats/:id/lists/:list_id
undocumented /chats/:id/lists/:list_id
DELETE /chats/:id/lists/:list_id — remove the chat from one of the lists.
id
string · path
list_id
string · path
/chats/example/lists/example
/chats
undocumented /chats
GET /chats — the caller's conversations, newest first.
/chats
/chats/:id
undocumented /chats/:id
GET /chats/:id — conversation details.
id
string · path
/chats/example
/chats/:id/messages
undocumented /chats/:id/messages
GET /chats/:id/messages — messages in a conversation.
id
string · path
/chats/example/messages
/chats/:id/messages/:msg_id/receipts
undocumented /chats/:id/messages/:msg_id/receipts
GET /chats/:id/messages/:msg_id/receipts — who has read a message.
id
string · path
msg_id
string · path
/chats/example/messages/example/receipts
/chats/:id/participants
undocumented /chats/:id/participants
GET /chats/:id/participants — list participants.
id
string · path
/chats/example/participants
/chats/lists
undocumented /chats/lists
GET /chats/lists — the caller's personal chat lists, ordered.
/chats/lists
/chats/:id/read
undocumented /chats/:id/read
PUT /chats/:id/read — mark a conversation as read.
id
string · path
/chats/example/read
/chats/:id/favourite
undocumented /chats/:id/favourite
PUT /chats/:id/favourite — mark the chat as a favourite (per-user).
id
string · path
/chats/example/favourite
/chats/:id/lists/:list_id
undocumented /chats/:id/lists/:list_id
PUT /chats/:id/lists/:list_id — add the chat to one of the caller's lists.
id
string · path
list_id
string · path
/chats/example/lists/example
/checklists/:checklist_id/workers/:worker_id/items/:item_id
Toggle an assignment item
checklist_id
string · path
worker_id
string · path
item_id
string · path
completed
propertyName
anything
/checklists/example/workers/example/items/example
/checklists/:checklist_id/workers
Assign a checklist to a worker
checklist_id
string · path
worker_id
string · min length: 1
due_date
string
anchor_date
string · max length: 10
responsible_worker_id
string
propertyName
anything
/checklists/example/workers
/checklists/:checklist_id/workers/:worker_id
Update assignment status
checklist_id
string · path
worker_id
string · path
status
due_date
string
anchor_date
string · max length: 10
responsible_worker_id
string
propertyName
anything
/checklists/example/workers/example
/checklists/:checklist_id
undocumented /checklists/:checklist_id
checklist_id
string · path
/checklists/example
/checklists/:checklist_id/workers/:worker_id
undocumented /checklists/:checklist_id/workers/:worker_id
checklist_id
string · path
worker_id
string · path
/checklists/example/workers/example
/checklists
undocumented /checklists
/checklists
/checklists/:checklist_id
undocumented /checklists/:checklist_id
checklist_id
string · path
/checklists/example
/checklists/:checklist_id/workers
undocumented /checklists/:checklist_id/workers
checklist_id
string · path
/checklists/example/workers
/checklists
Create a checklist template
type
title
string · min length: 1 · max length: 200
items
array
auto_assign
object
propertyName
anything
/checklists
/checklists/:checklist_id
Update a checklist template
checklist_id
string · path
title
string · min length: 1 · max length: 200
type
items
array
auto_assign
object
propertyName
anything
/checklists/example
/companies/:company_id
undocumented /companies/:company_id
DELETE /companies/:company_id — delete company (fails if contacts still linked).
company_id
string · path
/companies/example
/companies
undocumented /companies
GET /companies — list companies with filters.
/companies
/companies/:company_id
undocumented /companies/:company_id
GET /companies/:company_id — get company with contacts and recent interactions.
company_id
string · path
/companies/example
/companies/:company_id/interactions
undocumented /companies/:company_id/interactions
GET /companies/:company_id/interactions — interactions for a company (across all contacts).
company_id
string · path
/companies/example/interactions
/companies
Create a company
POST /companies — create a company.
name
string · min length: 1 · max length: 200
domain
string · max length: 200
industry
string · max length: 100
size
address
string · max length: 500
phone
string · max length: 50
annual_revenue
string · max length: 50
tags
array
relationships
array
owner_mrn
string
notes
string · max length: 5000
contact_name
string · max length: 200
contact_email
string · max length: 200
contact_title
string · max length: 100
contact_source
propertyName
anything
/companies
/companies/:company_id
Update a company
PUT /companies/:company_id — update a company.
company_id
string · path
name
string · min length: 1 · max length: 200
domain
string · max length: 200
industry
string · max length: 100
size
address
string · max length: 500
phone
string · max length: 50
annual_revenue
string · max length: 50
tags
array
relationships
array
archived
owner_mrn
string
notes
string · max length: 5000
propertyName
anything
/companies/example
/compensation/:compensation_id
undocumented /compensation/:compensation_id
compensation_id
string · path
/compensation/example
/compensation
undocumented /compensation
All workers with their latest compensation record.
/compensation
/compensation/changes
undocumented /compensation/changes
Recent compensation changes across all workers.
/compensation/changes
/workers/:worker_id/compensation
Add compensation record
worker_id
string · path
effective_date
string · min length: 1
items
array
reason
string · max length: 500
notes
string · max length: 2000
propertyName
anything
/workers/example/compensation
/contacts/suggestions/:suggestion_id
undocumented /contacts/suggestions/:suggestion_id
DELETE /contacts/suggestions/:suggestion_id — drop a suggestion outright.
suggestion_id
string · path
/contacts/suggestions/example
/contacts/relationships/:key
undocumented /contacts/relationships/:key
DELETE /contacts/relationships/:key: remove a workspace value from the list and from every record.
key
string · path
/contacts/relationships/example
/contacts/:contact_id
undocumented /contacts/:contact_id
DELETE /contacts/:contact_id — delete a contact with soft warning if MRN-referenced.
contact_id
string · path
/contacts/example
/contacts
undocumented /contacts
GET /contacts — list contacts with filters.
/contacts
/contacts/search
undocumented /contacts/search
GET /contacts/search: unified search across contacts and companies, best match first.
/contacts/search
/contacts/suggestions
undocumented /contacts/suggestions
GET /contacts/suggestions — the pending review queue, most active first.
/contacts/suggestions
/contacts/dashboard
undocumented /contacts/dashboard
GET /contacts/dashboard — everything the board renders, in one round trip. Every figure is aggregated in SQL rather than by counting serialized rows, so a workspace with fifty thousand contacts still renders a dashboard. The kit only ever fetches members and preferences itself; app data comes from here (specs/dashboard-kit.md, rule 1).
/contacts/dashboard
/contacts/exports
undocumented /contacts/exports
GET /contacts/exports — CSV of contacts or companies, filters applied. The same filters the directory is showing, so what downloads is what the person is looking at rather than the whole table.
/contacts/exports
/contacts/duplicates
undocumented /contacts/duplicates
GET /contacts/duplicates — merge candidates, worth-a-look first. Two cheap heuristics, both from the spec: the same name under different addresses, and the same address differing only in casing. No fuzzy matching: a wrong suggestion here costs somebody a destructive merge.
/contacts/duplicates
/contacts/settings
undocumented /contacts/settings
GET /contacts/settings — named embed configurations and snippets.
/contacts/settings
/contacts/relationships
undocumented /contacts/relationships
GET /contacts/relationships: the built-in values first, then the workspace's own.
/contacts/relationships
/contacts/support/settings
undocumented /contacts/support/settings
GET /contacts/support/settings: mailboxes, service levels, canned replies. Designated mailboxes come back WITH their address and provider, resolved here from our own rows. The settings page used to get its list from the mailbox picker instead, and once that endpoint became a search it answered an unqueried call with nothing, so the page showed "no support address yet" to workspaces that had one. The list of addresses answering support is this document, not a search over the directory, and it is read from the document now.
/contacts/support/settings
/contacts/support/mailboxes
undocumented /contacts/support/mailboxes
GET /contacts/support/mailboxes?q=: SEARCH, never the directory. This used to answer with every mailbox in the workspace and let the browser filter them. A workspace with ten thousand members put ten thousand addresses on the page, which is what got the settings screen rejected. It now answers a query with at most SEARCH_CAP rows, and answers nothing at all when asked for nothing: no query means no results, not everything. Refused mailboxes are returned DISABLED inside those results, never omitted. A workspace that owns an address it cannot designate needs to understand why; a dropped row reads as a missing mailbox rather than a missing capability, and somebody files that as a bug.
/contacts/support/mailboxes
/contacts/support/confirmations/:confirmation_id
undocumented /contacts/support/confirmations/:confirmation_id
GET /contacts/support/confirmations/:confirmation_id: has it arrived yet? Takes the pending id and nothing else. This opens a mailbox, so an address on the wire would make it an oracle: a caller could ask whether any mailbox we can reach contains a given string.
confirmation_id
string · path
/contacts/support/confirmations/example
/contacts/:contact_id
undocumented /contacts/:contact_id
GET /contacts/:contact_id — get contact with company info and recent interactions.
contact_id
string · path
/contacts/example
/contacts/:contact_id/interactions
undocumented /contacts/:contact_id/interactions
GET /contacts/:contact_id/interactions — interactions for a contact.
contact_id
string · path
/contacts/example/interactions
/contacts/reports
undocumented /contacts/reports
GET /contacts/reports: every helpdesk figure, in one round trip. Aggregated in SQL rather than by counting serialized rows, so a workspace with fifty thousand conversations still renders the board. Response times are measured from ``first_response_at``, which is stamped once by the first non-internal staff message, so a conversation nobody has answered contributes to the backlog figures and to nothing else. Averaging it in as a zero would report a helpdesk answering instantly while its customers waited.
/contacts/reports
/contacts/suggestions/:suggestion_id
Accept or dismiss a contact suggestion
PATCH /contacts/suggestions/:suggestion_id — accept or dismiss. ``accepted`` promotes the address to a real contact (with domain/company auto-link, as a manual create would) and clears the suggestion. ``dismissed`` hides it for good — the upsert keeps it dismissed thereafter.
suggestion_id
string · path
status
name
string · min length: 1 · max length: 200
company_id
string
propertyName
anything
/contacts/suggestions/example
/contacts
Create a contact
POST /contacts — create a contact with domain extraction and auto company linking.
name
string · min length: 1 · max length: 200
email
string · max length: 200
phone
string · max length: 50
mobile
string · max length: 50
secondary_email
string · max length: 200
title
string · max length: 100
department
string · max length: 100
company_id
string
linkedin_url
string · max length: 500
website
string · max length: 500
social_url
string · max length: 500
address
string · max length: 500
tags
array
role
string · max length: 50
lifecycle_stage
preferred_channel
timezone
string · max length: 60
birthday
string · max length: 10
avatar_url
string · max length: 500
notes
string · max length: 5000
custom_fields
array
relationships
array
owner_mrn
string
source
propertyName
anything
/contacts
/contacts/imports
Import contacts from CSV
POST /contacts/imports: CSV import with a column mapping. Deduped by email: a row whose address already exists UPDATES that contact rather than creating a second one. That is the whole point. An import that silently doubles a directory is worse than one that refuses to run. Rows without a usable email are reported back rather than dropped silently, so the person importing can see exactly what did not land.
csv
string · min length: 1 · max length: 2000000
mappings
array
has_header
company_id
string
propertyName
anything
/contacts/imports
/contacts/settings/widget-keys
undocumented /contacts/settings/widget-keys
POST /contacts/settings/widget-keys — rotate the first embed's key. Kept for callers that predate named embeds. Prefer ``POST /contacts/settings/embeds/:embed_id/rotate-key``.
/contacts/settings/widget-keys
/contacts/settings/embeds/:embed_id/rotate-key
undocumented /contacts/settings/embeds/:embed_id/rotate-key
POST /contacts/settings/embeds/:embed_id/rotate-key — rotate one embed.
embed_id
string · path
/contacts/settings/embeds/example/rotate-key
/contacts/relationships
Add a relationship value
POST /contacts/relationships: add a relationship value of the workspace's own.
label
string · min length: 1 · max length: 40
propertyName
anything
/contacts/relationships
/contacts/:contact_id/merges
Merge a duplicate into this contact
POST /contacts/:id/merges — fold a duplicate into this contact. The survivor keeps everything it already had; blanks fill from the duplicate. Interactions, conversations and timeline rows re-point, then the duplicate row is deleted and consuming apps are told to re-point their party projections. Deliberately not reversible, and deliberately not a soft delete: a tombstone row would keep the duplicate resolvable through every lookup that made it a problem in the first place.
contact_id
string · path
duplicate_id
string · min length: 1
propertyName
anything
/contacts/example/merges
/contacts/settings
Configure the website chat widget
PUT /contacts/settings — create or update named website chat embeds. Keys are never taken from the client. Enabling an embed for the first time mints one; rotation is its own endpoint.
embeds
array
widget
object
dormant_after_days
integer · min: 1 · max: 3650
propertyName
anything
/contacts/settings
/contacts/:contact_id
Update a contact
PUT /contacts/:contact_id — update a contact.
contact_id
string · path
phone_number
string · max length: 50
street
string · max length: 300
city
string · max length: 100
state
string · max length: 100
postal_code
string · max length: 20
country
string · max length: 100
propertyName
anything
/contacts/example
/contacts/:contact_id/state
Override a contact's state
PUT /contacts/:id/state — a human overriding the derived face. Recorded as ``manual`` and labelled as such in the UI, because a state somebody typed and a state the evidence produced are different claims. It lasts until the next real signal, which then takes the wheel back.
contact_id
string · path
state
reason
string · max length: 200
propertyName
anything
/contacts/example/state
/conversations
undocumented /conversations
GET /conversations: the ticket list. Filters: status, status_key, type_key, assignee_mrn, priority, contact_id, channel, overdue, q.
/conversations
/conversations/:conversation_id
undocumented /conversations/:conversation_id
GET /conversations/:id — the thread, including internal notes. This is a staff route behind contacts.conversations.view; internal notes are stripped only on the visitor-facing widget routes.
conversation_id
string · path
/conversations/example
/conversations/:conversation_id
Assign, prioritise or resolve a conversation
PATCH /conversations/:id — status, assignee, priority and tag moves. Resolution is the CSAT moment: it stamps resolved_at, logs the thread as a touchpoint on the contact, and tells the spawning surface to prompt for a rating.
conversation_id
string · path
status
status_key
string · max length: 40
type_key
string · max length: 40
priority
assignee_mrn
string · max length: 200
tags
array
contact_id
string · max length: 60
propertyName
anything
/conversations/example
/contacts/support/confirmations
Confirm an address as a support inbox
POST /contacts/support/confirmations: mail an address to prove it works. Named by mailbox id, never by address. The id is resolved through the caller's scoped connection, so a mailbox this workspace does not hold is simply not found, and the address we send to comes off OUR row rather than off the request.
mailbox_id
string · min length: 1 · max length: 80
propertyName
anything
/contacts/support/confirmations
/conversations
Open a ticket for a contact
POST /conversations: a ticket staff opened for a contact. No first reply is owed on it, because nobody outside is waiting for one. The resolution clock runs from the moment it opens, exactly as it does elsewhere.
contact_id
string · min length: 1 · max length: 60
subject
string · min length: 1 · max length: 200
body
string · min length: 1 · max length: 10000
priority
type_key
string · max length: 40
assignee_mrn
string · max length: 200
propertyName
anything
/conversations
/conversations/:conversation_id/messages
Reply in a conversation or add an internal note
POST /conversations/:id/messages — a staff reply, or an internal note. Any holder of contacts.conversations.manage may reply in any thread; assignee_mrn is ownership, never exclusivity. An internal note is stored and shown to colleagues but never emitted and never delivered to the visitor.
conversation_id
string · path
body
string · min length: 1 · max length: 10000
is_internal
propertyName
anything
/conversations/example/messages
/conversations/:conversation_id/drafts
undocumented /conversations/:conversation_id/drafts
POST /conversations/:id/drafts: start a co-written reply. Composing a reply IS composing mail, so this creates a MAIL draft through the mail layer's own creator rather than a table of its own. Contacts owns no mail table, and a second draft store would be a second thing to keep in step with sending. The draft is created BEFORE the socket is opened, which is what lets the shared transport refuse an unknown id outright instead of trusting that a client will save one shortly.
conversation_id
string · path
/conversations/example/drafts
/conversations/:conversation_id/drafts/:draft_id/send
undocumented /conversations/:conversation_id/drafts/:draft_id/send
POST /conversations/:id/drafts/:draft_id/send: send the co-written reply. Reads the draft's body, stores it on the conversation like any other staff reply, and lets it out through the one send path, from the conversation's own mailbox.
conversation_id
string · path
draft_id
string · path
/conversations/example/drafts/example/send
/contacts/support/settings
Configure support mailboxes and service levels
PUT /contacts/support/settings: designate mailboxes and set service levels. A mailbox can only be designated if it is one this workspace actually hosts. Anything else is refused rather than stored and quietly ignored: a workspace that thinks it has designated a Google Workspace address and hears nothing conclude the feature is broken.
mailboxes
array
auto_reply_enabled
auto_reply_body
string
sla
object
resolution
object
canned_replies
array
statuses
array
types
array
propertyName
anything
/contacts/support/settings
/coupons/:code/redemptions
undocumented /coupons/:code/redemptions
POST /coupons/:code/redemptions — apply a coupon to the current workspace.
code
string · path
/coupons/example/redemptions
/finance/credit-notes/:entry_id
Issue/void credit note
entry_id
string · path
status
propertyName
anything
/finance/credit-notes/example
/finance/credit-notes
Create a credit note
date
string · min length: 10
items
array
source_entry_id
string · min length: 1
contact_mrn
string
company_mrn
string
currency
exchange_rate
number
memo
string · max length: 5000
adjustments
array
dimensions
idempotency_key
string · max length: 100
propertyName
anything
/finance/credit-notes
/finance/credit-notes/:entry_id/allocations
Set credit against an invoice
entry_id
string · path
entry_id
string · min length: 1
amount
number
entry_amount
number
propertyName
anything
/finance/credit-notes/example/allocations
/finance/credit-notes/:entry_id/pdfs
Generate credit note PDF
entry_id
string · path
template
string · max length: 100
propertyName
anything
/finance/credit-notes/example/pdfs
/finance/credit-notes/:entry_id/sends
Email a credit note
entry_id
string · path
to
string · min length: 1 · max length: 500
cc
string · max length: 500
subject
string · max length: 300
message
string · max length: 5000
propertyName
anything
/finance/credit-notes/example/sends
/finance/credit-notes/:entry_id
Update a credit note
entry_id
string · path
date
string · min length: 10
items
array
contact_mrn
string
company_mrn
string
currency
exchange_rate
number
memo
string · max length: 5000
adjustments
array
dimensions
propertyName
anything
/finance/credit-notes/example
/crm/leads
undocumented /crm/leads
Contacts with no open deal, their own or their company's, ranked by score.
/crm/leads
/crm/reports/pipeline
undocumented /crm/reports/pipeline
/crm/reports/pipeline
/crm/reports/performance
undocumented /crm/reports/performance
/crm/reports/performance
/crm/reports/forecast
undocumented /crm/reports/forecast
/crm/reports/forecast
/crm/reports/activity
undocumented /crm/reports/activity
Activity report: target progress per rep.
/crm/reports/activity
/crm/reports/funnel
undocumented /crm/reports/funnel
Stage entry counts + conversion, from the indexed timeline.
/crm/reports/funnel
/crm/reports/trends
undocumented /crm/reports/trends
Monthly won/lost counts and won value (grouped by currency), last 12 months.
/crm/reports/trends
/crm/reports/losses
undocumented /crm/reports/losses
Loss reasons breakdown (count + value by currency).
/crm/reports/losses
/deals/:deal_id
undocumented /deals/:deal_id
deal_id
string · path
/deals/example
/deals/:deal_id/line-items/:item_id
undocumented /deals/:deal_id/line-items/:item_id
deal_id
string · path
item_id
string · path
/deals/example/line-items/example
/deals/:deal_id/links/:link_id
undocumented /deals/:deal_id/links/:link_id
deal_id
string · path
link_id
string · path
/deals/example/links/example
/deals/:deal_id/attachments/:file_id
undocumented /deals/:deal_id/attachments/:file_id
deal_id
string · path
file_id
string · path
/deals/example/attachments/example
/deals/:deal_id/checklist-items/:item_id
undocumented /deals/:deal_id/checklist-items/:item_id
deal_id
string · path
item_id
string · path
/deals/example/checklist-items/example
/deals
undocumented /deals
Global deal list. pipeline_id is an optional filter, no longer mandatory.
/deals
/deals/:deal_id
undocumented /deals/:deal_id
deal_id
string · path
/deals/example
/deals/:deal_id/line-items
undocumented /deals/:deal_id/line-items
deal_id
string · path
/deals/example/line-items
/deals/:deal_id/links
undocumented /deals/:deal_id/links
deal_id
string · path
/deals/example/links
/deals/:deal_id/activities
undocumented /deals/:deal_id/activities
deal_id
string · path
/deals/example/activities
/deals/:deal_id/checklist-items
undocumented /deals/:deal_id/checklist-items
deal_id
string · path
/deals/example/checklist-items
/deals/:deal_id/stage
Move a deal to another stage
deal_id
string · path
stage_id
string · min length: 1
pipeline_id
string
loss_reason
string · max length: 1000
propertyName
anything
/deals/example/stage
/deals
Create a deal
pipeline_id
string
title
string · min length: 1 · max length: 300
value
number
currency
string · min length: 3 · max length: 3
stage_id
string
contact_mrn
string
company_mrn
string
owner_mrn
string
expected_close_date
string
source
line_items
array
tags
array
propertyName
anything
/deals
/deals/:deal_id/line-items
Add a line item to a deal
deal_id
string · path
name
string · min length: 1 · max length: 200
product_mrn
string
quantity
number
unit_price
number
currency
string
period
propertyName
anything
/deals/example/line-items
/deals/:deal_id/links
Mint a deal room link for a customer
deal_id
string · path
label
string · max length: 200
propertyName
anything
/deals/example/links
/deals/:deal_id/attachments
Attach a shared file to the deal room
deal_id
string · path
mrn
string · min length: 15 · max length: 200
name
string · min length: 1 · max length: 300
url
string · min length: 1 · max length: 500
share_id
string · max length: 100
propertyName
anything
/deals/example/attachments
/deals/:deal_id/activities
Add a note to a deal
deal_id
string · path
content
string · min length: 1 · max length: 20000
application_id
string · max length: 100
propertyName
anything
/deals/example/activities
/deals/:deal_id/checklist-items
Add a checklist item to a deal
deal_id
string · path
label
string · min length: 1 · max length: 200
stage_id
string
assignee_mrn
string
due_date
string
propertyName
anything
/deals/example/checklist-items
/deals/:deal_id/quote-requests
Ask Finance to draft a quote from this deal
POST /deals/:deal_id/quote-requests. Emits deal.quote_requested; Finance drafts the quote from the line items (apps/finance/events.py).
deal_id
string · path
memo
string · max length: 2000
propertyName
anything
/deals/example/quote-requests
/deals/:deal_id
Update a deal
deal_id
string · path
title
string · min length: 1 · max length: 300
value
number
currency
string · min length: 3 · max length: 3
contact_mrn
string
company_mrn
string
owner_mrn
string
expected_close_date
string
source
tags
array
loss_reason
string
proposal
string · max length: 100000
propertyName
anything
/deals/example
/deals/:deal_id/line-items/:item_id
Update a deal line item
deal_id
string · path
item_id
string · path
name
string · min length: 1 · max length: 200
product_mrn
string
quantity
number
unit_price
number
currency
string
period
position
integer
propertyName
anything
/deals/example/line-items/example
/deals/:deal_id/checklist-items/:item_id
Update a deal checklist item
deal_id
string · path
item_id
string · path
done
label
string · min length: 1 · max length: 200
assignee_mrn
string
due_date
string
position
integer
propertyName
anything
/deals/example/checklist-items/example
/decks/trash
undocumented /decks/trash
DELETE /decks/trash. Destroy every trashed deck the caller manages.
/decks/trash
/decks/trash/:id
undocumented /decks/trash/:id
DELETE /decks/trash/:id. Destroy a trashed deck. Gate loaded ctx.authz.deck.
id
string · path
/decks/trash/example
/decks/:id
undocumented /decks/:id
DELETE /decks/:id. Soft-delete. Grants stay so restore still works.
id
string · path
/decks/example
/decks
undocumented /decks
GET /decks. Decks the caller can access.
/decks
/decks/trash
undocumented /decks/trash
GET /decks/trash. Decks in the trash that the caller can restore.
/decks/trash
/decks/:id
undocumented /decks/:id
GET /decks/:id. Metadata + deck_json. Gate loaded ctx.authz.deck.
id
string · path
/decks/example
/decks/:id/exports/:format
undocumented /decks/:id/exports/:format
GET /decks/:id/exports/:format: the deck as an .odp download.
id
string · path
format
string · path
/decks/example/exports/example
/decks/:id/assets
undocumented /decks/:id/assets
GET /decks/:id/assets. Images uploaded to this deck. Gate loaded ctx.authz.deck.
id
string · path
/decks/example/assets
/deliverables/:deliverable_id
undocumented /deliverables/:deliverable_id
Delete a deliverable. Linked tasks keep existing — their deliverable link clears via the ON DELETE SET NULL foreign key.
deliverable_id
string · path
/deliverables/example
/deliverables
undocumented /deliverables
GET /deliverables?board_id=...&q=... — list a board's deliverables.
/deliverables
/deliverables
Create a deliverable
board_id
string
name
string · min length: 1 · max length: 200
due_date
string · min length: 1
description
string · max length: 5000
status
schedule_id
string
owner_mrn
string
propertyName
anything
/deliverables
/deliverables/:deliverable_id
Update a deliverable
deliverable_id
string · path
name
string · min length: 1 · max length: 200
description
string · max length: 5000
due_date
string
status
schedule_id
string
owner_mrn
string
propertyName
anything
/deliverables/example
/demo-requests/availability
undocumented /demo-requests/availability
GET /demo-requests/availability — open demo slots for the next weekdays.
/demo-requests/availability
/departments/:department_id
undocumented /departments/:department_id
department_id
string · path
/departments/example
/departments/:department_id/members/:worker_id
undocumented /departments/:department_id/members/:worker_id
DELETE /departments/:department_id/members/:worker_id. The method is the verb, so there is no PATCH-to-null variant of this route.
department_id
string · path
worker_id
string · path
/departments/example/members/example
/departments
undocumented /departments
/departments
/departments/:department_id
undocumented /departments/:department_id
department_id
string · path
/departments/example
/departments/:department_id
Update a department
department_id
string · path
name
string · min length: 1 · max length: 100
description
string · max length: 1000
parent_id
string
head_mrn
string
propertyName
anything
/departments/example
/departments
Create a department
name
string · min length: 1 · max length: 100
description
string · max length: 1000
parent_id
string
head_mrn
string
propertyName
anything
/departments
/departments/:department_id/members/:worker_id
undocumented /departments/:department_id/members/:worker_id
PUT /departments/:department_id/members/:worker_id. Idempotent: putting a worker into the department they are already in is a no-op that still answers with the worker, which is what PUT should do.
department_id
string · path
worker_id
string · path
/departments/example/members/example
/finance/dimensions/:dimension_key
Update a dimension
dimension_key
string · path
name
string · min length: 1 · max length: 100
key
string · min length: 1 · max length: 50
values
array
propertyName
anything
/finance/dimensions/example
/finance/dimensions
Define a dimension
name
string · min length: 1 · max length: 100
key
string · min length: 1 · max length: 50
values
array
propertyName
anything
/finance/dimensions
/sign/envelopes/:envelope_id
Update document metadata
PATCH /sign/envelopes/:envelope_id — update metadata OR transition state (sent/voided).
envelope_id
string · path
title
string · min length: 1 · max length: 300
subject
string · max length: 300
message
string · max length: 2000
signing_order_mode
jurisdiction
string · max length: 10
expires_at
string
status
reason
string · max length: 1000
propertyName
anything
/sign/envelopes/example
/sign/envelopes
Create a draft document
POST /sign/envelopes — create a draft (optionally cloning ?template_id).
title
string · min length: 1 · max length: 300
subject
string · max length: 300
message
string · max length: 2000
template_id
string
signing_order_mode
jurisdiction
string · max length: 10
is_template
source_mrn
string · max length: 200
propertyName
anything
/sign/envelopes
/sign/envelopes/:envelope_id/documents
Append a source PDF to the envelope
POST /sign/envelopes/:envelope_id/documents {storage_key, title, page_count} — append a source PDF. The first add on a legacy envelope promotes its single PDF into a row, so an envelope is always pure-legacy or pure-rows.
envelope_id
string · path
storage_key
string · min length: 1 · max length: 500
title
string · max length: 300
page_count
integer
propertyName
anything
/sign/envelopes/example/documents
/sign/envelopes/:envelope_id/exports
Save sealed document to Files
POST /sign/envelopes/:envelope_id/exports {target:"files"} — copy the sealed PDF into the caller's Files. Sign never auto-mirrors; this explicit action is the only path.
envelope_id
string · path
target
propertyName
anything
/sign/envelopes/example/exports
/sign/envelopes/:envelope_id/source
Attach the uploaded source PDF
PUT /sign/envelopes/:envelope_id/source {storage_key, page_count} — attach the uploaded source PDF SYNCHRONOUSLY. The client calls this right after PUTting the file to R2, so the document is attached deterministically instead of depending on the async upload-confirmed event (which, if the event bus doesn't deliver it, leaves the PDF unattached forever). The key must live under this workspace's own sign/ prefix — a client can't point the envelope at another workspace's or app's object.
envelope_id
string · path
storage_key
string · min length: 1 · max length: 500
page_count
integer
propertyName
anything
/sign/envelopes/example/source
/sign/settings
Choose the contract template
PUT /sign/settings {contract_template_id}: choose the contract template. An empty value clears the choice, which switches the cross-app handoff off: requests then arrive and are ignored rather than drafting the wrong document. Written through the registered config contract so the platform Settings editor and this picker stay one document with one validator.
contract_template_id
string · max length: 64
propertyName
anything
/sign/settings
/elevations
undocumented /elevations
DELETE /elevations — leave admin mode without waiting for the timer.
/elevations
/elevations/current
undocumented /elevations/current
GET /elevations/current — the caller's window, for the shell's ring. `totp_enabled` says which factor the prompt should ask for, because only the server knows. Without it the modal had to guess, guessed password, and an account with TOTP paid for a password that api_start_elevation never even looks at before being asked for a code anyway. Having a second factor should cost fewer steps, not more.
/elevations/current
/workers/:worker_id/employment
Add an employment record
worker_id
string · path
job_title
string · min length: 1 · max length: 200
start_date
string · min length: 1 · max length: 10
member_mrn
string · max length: 120
employment_type
end_date
string · max length: 10
reason
string · max length: 500
reminder_enabled
reminder_days_before
integer
propertyName
anything
/workers/example/employment
/workers/:worker_id/employment/termination
Terminate a worker's employment
Terminate employment: close every open/future contract at the effective date, set status=terminated, and fire the terminated event. Reason is required.
worker_id
string · path
reason
string · min length: 1 · max length: 500
effective_date
string · min length: 1 · max length: 10
propertyName
anything
/workers/example/employment/termination
/workers/:worker_id/employment/:record_id
Update an employment record
worker_id
string · path
record_id
string · path
job_title
string · min length: 1 · max length: 200
employment_type
start_date
string · max length: 10
end_date
string · max length: 10
reason
string · max length: 500
reminder_enabled
reminder_days_before
integer
propertyName
anything
/workers/example/employment/example
/exchanges/:exchange_id
undocumented /exchanges/:exchange_id
GET /exchanges/:exchange_id — one audit row, for the mint-capable caller only, which since the shared-only amendment means a workspace owner/admin. Anyone else gets the same 404 as a nonexistent id. No list-all-workspace-exchanges in V1.
exchange_id
string · path
/exchanges/example
/sign/envelopes/:envelope_id/fields/:field_id
Move/resize/reassign a field
PATCH /sign/envelopes/:envelope_id/fields/:field_id — move/resize/reassign a field.
envelope_id
string · path
field_id
string · path
role
string · min length: 1 · max length: 100
recipient_id
string
kind
page_number
integer
nx
number
ny
number
nw
number
nh
number
label
string · max length: 200
required
default_value
string
options
object
propertyName
anything
/sign/envelopes/example/fields/example
/sign/envelopes/:envelope_id/fields
Add field placements
POST /sign/envelopes/:envelope_id/fields — add one or more field placements (bulk).
envelope_id
string · path
fields
array
propertyName
anything
/sign/envelopes/example/fields
/file-statistics
undocumented /file-statistics
GET /file-statistics — the caller's own storage and sharing overview. One call, because the dashboard draws every widget at once and a dozen round trips would show a dozen skeletons resolving at different times. Each aggregate is indexed on (workspace_id, owner_mrn, ...).
/file-statistics
/files/:file_id
undocumented /files/:file_id
file_id
string · path
/files/example
/files/:file_id/stars
undocumented /files/:file_id/stars
DELETE /files/:file_id/stars — remove the current member's star.
file_id
string · path
/files/example/stars
/files/:file_id/permissions
undocumented /files/:file_id/permissions
file_id
string · path
/files/example/permissions
/files
undocumented /files
/files
/files/:file_id
undocumented /files/:file_id
file_id
string · path
/files/example
/files/:file_id/download
undocumented /files/:file_id/download
file_id
string · path
/files/example/download
/files/:file_id/preview
undocumented /files/:file_id/preview
GET /files/:file_id/preview — presigned URL for inline preview.
file_id
string · path
/files/example/preview
/files/:file_id/versions
undocumented /files/:file_id/versions
GET /files/:file_id/versions — version history, newest first.
file_id
string · path
/files/example/versions
/files/:file_id/permissions
undocumented /files/:file_id/permissions
file_id
string · path
/files/example/permissions
/files/:file_id
Update a file
file_id
string · path
name
string · min length: 1 · max length: 255
folder_id
string
is_starred
restore_version_id
string
propertyName
anything
/files/example
/files/:file_id/stars
undocumented /files/:file_id/stars
POST /files/:file_id/stars — star a file for the current member.
file_id
string · path
/files/example/stars
/files/:file_id/copies
Copy a file
POST /files/:file_id/copies — duplicate a file (optionally into another folder). View access on the source suffices; the destination needs write.
file_id
string · path
folder_id
string
propertyName
anything
/files/example/copies
/files/bulk
Bulk file operation
action
ids
array
folder_id
string
propertyName
anything
/files/bulk
/finance/quotes/:entry_id
undocumented /finance/quotes/:entry_id
entry_id
string · path
/finance/quotes/example
/finance/purchase-orders/:entry_id
undocumented /finance/purchase-orders/:entry_id
entry_id
string · path
/finance/purchase-orders/example
/finance/orders/:entry_id
undocumented /finance/orders/:entry_id
entry_id
string · path
/finance/orders/example
/finance/invoices/:entry_id
undocumented /finance/invoices/:entry_id
entry_id
string · path
/finance/invoices/example
/finance/invoices/:entry_id/attachments/:attachment_id
undocumented /finance/invoices/:entry_id/attachments/:attachment_id
entry_id
string · path
attachment_id
string · path
/finance/invoices/example/attachments/example
/finance/bills/:entry_id
undocumented /finance/bills/:entry_id
entry_id
string · path
/finance/bills/example
/finance/credit-notes/:entry_id
undocumented /finance/credit-notes/:entry_id
entry_id
string · path
/finance/credit-notes/example
/finance/credit-notes/:entry_id/allocations/:target_entry_id
undocumented /finance/credit-notes/:entry_id/allocations/:target_entry_id
entry_id
string · path
target_entry_id
string · path
/finance/credit-notes/example/allocations/example
/finance/credit-notes/:entry_id/attachments/:attachment_id
undocumented /finance/credit-notes/:entry_id/attachments/:attachment_id
entry_id
string · path
attachment_id
string · path
/finance/credit-notes/example/attachments/example
/finance/purchase-credit-notes/:entry_id
undocumented /finance/purchase-credit-notes/:entry_id
entry_id
string · path
/finance/purchase-credit-notes/example
/finance/purchase-credit-notes/:entry_id/allocations/:target_entry_id
undocumented /finance/purchase-credit-notes/:entry_id/allocations/:target_entry_id
entry_id
string · path
target_entry_id
string · path
/finance/purchase-credit-notes/example/allocations/example
/finance/journal-entries/:entry_id
undocumented /finance/journal-entries/:entry_id
entry_id
string · path
/finance/journal-entries/example
/finance/accounts/:account_id
undocumented /finance/accounts/:account_id
account_id
string · path
/finance/accounts/example
/finance/bank-imports/:import_id
undocumented /finance/bank-imports/:import_id
import_id
string · path
/finance/bank-imports/example
/finance/requests/:request_id
undocumented /finance/requests/:request_id
DELETE /finance/requests/:id — the owner withdraws a submitted request.
request_id
string · path
/finance/requests/example
/finance/links/:link_id
undocumented /finance/links/:link_id
link_id
string · path
/finance/links/example
/finance/payment-credentials/:provider
undocumented /finance/payment-credentials/:provider
provider
string · path
/finance/payment-credentials/example
/finance/bank-connections/:id
undocumented /finance/bank-connections/:id
id
string · path
/finance/bank-connections/example
/finance/settings/logo
undocumented /finance/settings/logo
DELETE /finance/settings/logo: take the logo off every document. Deletes the object for real, because "remove my logo" has to mean the image stops being served, not merely that documents stop pointing at it. The key is dropped too, so the next upload mints a fresh unguessable one rather than resurrecting a URL that was already handed out.
/finance/settings/logo
/finance/fiscal-periods/:period_id
undocumented /finance/fiscal-periods/:period_id
period_id
string · path
/finance/fiscal-periods/example
/finance/dimensions/:dimension_key
undocumented /finance/dimensions/:dimension_key
dimension_key
string · path
/finance/dimensions/example
/finance/tax-rates/:tax_id
undocumented /finance/tax-rates/:tax_id
tax_id
string · path
/finance/tax-rates/example
/finance/payment-terms/:term_id
undocumented /finance/payment-terms/:term_id
term_id
string · path
/finance/payment-terms/example
/finance/bank-rules/:rule_id
undocumented /finance/bank-rules/:rule_id
rule_id
string · path
/finance/bank-rules/example
/finance/budgets/:budget_id
undocumented /finance/budgets/:budget_id
budget_id
string · path
/finance/budgets/example
/finance/recurring-entries/:recurring_id
undocumented /finance/recurring-entries/:recurring_id
recurring_id
string · path
/finance/recurring-entries/example
/finance/quotes
undocumented /finance/quotes
/finance/quotes
/finance/quotes/:entry_id
undocumented /finance/quotes/:entry_id
entry_id
string · path
/finance/quotes/example
/finance/purchase-orders
undocumented /finance/purchase-orders
/finance/purchase-orders
/finance/purchase-orders/:entry_id
undocumented /finance/purchase-orders/:entry_id
entry_id
string · path
/finance/purchase-orders/example
/finance/purchase-orders/:entry_id/receipts
undocumented /finance/purchase-orders/:entry_id/receipts
entry_id
string · path
/finance/purchase-orders/example/receipts
/finance/orders
undocumented /finance/orders
/finance/orders
/finance/orders/:entry_id
undocumented /finance/orders/:entry_id
entry_id
string · path
/finance/orders/example
/finance/orders/:entry_id/fulfillments
undocumented /finance/orders/:entry_id/fulfillments
entry_id
string · path
/finance/orders/example/fulfillments
/finance/invoices
undocumented /finance/invoices
/finance/invoices
/finance/invoices/:entry_id
undocumented /finance/invoices/:entry_id
entry_id
string · path
/finance/invoices/example
/finance/invoices/:entry_id/payments
undocumented /finance/invoices/:entry_id/payments
entry_id
string · path
/finance/invoices/example/payments
/finance/invoices/:entry_id/ledger-lines
undocumented /finance/invoices/:entry_id/ledger-lines
entry_id
string · path
/finance/invoices/example/ledger-lines
/finance/invoices/:entry_id/pdfs
undocumented /finance/invoices/:entry_id/pdfs
entry_id
string · path
/finance/invoices/example/pdfs
/finance/bills
undocumented /finance/bills
/finance/bills
/finance/bills/:entry_id
undocumented /finance/bills/:entry_id
entry_id
string · path
/finance/bills/example
/finance/bills/:entry_id/payments
undocumented /finance/bills/:entry_id/payments
entry_id
string · path
/finance/bills/example/payments
/finance/bills/:entry_id/ledger-lines
undocumented /finance/bills/:entry_id/ledger-lines
entry_id
string · path
/finance/bills/example/ledger-lines
/finance/credit-notes
undocumented /finance/credit-notes
/finance/credit-notes
/finance/credit-notes/:entry_id
undocumented /finance/credit-notes/:entry_id
entry_id
string · path
/finance/credit-notes/example
/finance/credit-notes/:entry_id/ledger-lines
undocumented /finance/credit-notes/:entry_id/ledger-lines
entry_id
string · path
/finance/credit-notes/example/ledger-lines
/finance/credit-notes/:entry_id/pdfs
undocumented /finance/credit-notes/:entry_id/pdfs
entry_id
string · path
/finance/credit-notes/example/pdfs
/finance/purchase-credit-notes
undocumented /finance/purchase-credit-notes
/finance/purchase-credit-notes
/finance/purchase-credit-notes/:entry_id
undocumented /finance/purchase-credit-notes/:entry_id
entry_id
string · path
/finance/purchase-credit-notes/example
/finance/purchase-credit-notes/:entry_id/ledger-lines
undocumented /finance/purchase-credit-notes/:entry_id/ledger-lines
entry_id
string · path
/finance/purchase-credit-notes/example/ledger-lines
/finance/journal-entries
undocumented /finance/journal-entries
/finance/journal-entries
/finance/journal-entries/:entry_id
undocumented /finance/journal-entries/:entry_id
entry_id
string · path
/finance/journal-entries/example
/finance/journal-entries/:entry_id/ledger-lines
undocumented /finance/journal-entries/:entry_id/ledger-lines
entry_id
string · path
/finance/journal-entries/example/ledger-lines
/finance/accounts
undocumented /finance/accounts
List the chart of accounts. Filters: ?type=, ?active=, ?bank=true, ?q= (matches code or name — the Lookup widget in every account picker sends q). Raw SQL because supersql renders OR conditions unparenthesized, which would break workspace scoping.
/finance/accounts
/finance/accounts/:account_id
undocumented /finance/accounts/:account_id
account_id
string · path
/finance/accounts/example
/finance/accounts/:account_id/ledger-lines
undocumented /finance/accounts/:account_id/ledger-lines
account_id
string · path
/finance/accounts/example/ledger-lines
/finance/chart-advice
undocumented /finance/chart-advice
Advisory guidance for the new-account form (see core.forms Form.advice). Returns the derived normal balance, a suggested free code in the chosen type's block, and a warning when the typed code sits in a different type's block. Nothing here rejects anything, because the code-range convention is advisory by design (ACCOUNT_CODE_RANGES explains why), and the rule that IS enforceable is enforced in api_create_account instead.
/finance/chart-advice
/finance/ledger
undocumented /finance/ledger
/finance/ledger
/finance/ledger/:line_id
undocumented /finance/ledger/:line_id
line_id
string · path
/finance/ledger/example
/finance/payments
undocumented /finance/payments
/finance/payments
/finance/payments/:payment_id
undocumented /finance/payments/:payment_id
payment_id
string · path
/finance/payments/example
/finance/payments/:payment_id/reversals
undocumented /finance/payments/:payment_id/reversals
payment_id
string · path
/finance/payments/example/reversals
/finance/bank-imports
undocumented /finance/bank-imports
/finance/bank-imports
/finance/bank-imports/:import_id
undocumented /finance/bank-imports/:import_id
import_id
string · path
/finance/bank-imports/example
/finance/bank-imports/:import_id/matches
undocumented /finance/bank-imports/:import_id/matches
import_id
string · path
/finance/bank-imports/example/matches
/finance/requests
undocumented /finance/requests
GET /finance/requests — reviewers see all, everyone else their own. The scope is deposited by the authz chain (scope_requests).
/finance/requests
/finance/requests/:request_id
undocumented /finance/requests/:request_id
request_id
string · path
/finance/requests/example
/finance/quotes/:entry_id/links
undocumented /finance/quotes/:entry_id/links
entry_id
string · path
/finance/quotes/example/links
/finance/invoices/:entry_id/links
undocumented /finance/invoices/:entry_id/links
entry_id
string · path
/finance/invoices/example/links
/finance/credit-notes/:entry_id/links
undocumented /finance/credit-notes/:entry_id/links
entry_id
string · path
/finance/credit-notes/example/links
/finance/payment-credentials
undocumented /finance/payment-credentials
/finance/payment-credentials
/finance/bank-connections
undocumented /finance/bank-connections
/finance/bank-connections
/finance/reconciliations
undocumented /finance/reconciliations
/finance/reconciliations
/finance/reconciliations/:recon_id
undocumented /finance/reconciliations/:recon_id
recon_id
string · path
/finance/reconciliations/example
/finance/settings
undocumented /finance/settings
/finance/settings
/finance/fiscal-periods
undocumented /finance/fiscal-periods
/finance/fiscal-periods
/finance/fiscal-periods/:period_id/revaluation-preview
undocumented /finance/fiscal-periods/:period_id/revaluation-preview
GET /finance/fiscal-periods/:period_id/revaluation-preview?as_of=...
period_id
string · path
/finance/fiscal-periods/example/revaluation-preview
/finance/fiscal-periods/:period_id/revaluations
undocumented /finance/fiscal-periods/:period_id/revaluations
GET /finance/fiscal-periods/:period_id/revaluations
period_id
string · path
/finance/fiscal-periods/example/revaluations
/finance/dimensions
undocumented /finance/dimensions
/finance/dimensions
/finance/dimensions/:dimension_key/values
undocumented /finance/dimensions/:dimension_key/values
dimension_key
string · path
/finance/dimensions/example/values
/finance/tax-rates
undocumented /finance/tax-rates
/finance/tax-rates
/finance/payment-terms
undocumented /finance/payment-terms
/finance/payment-terms
/finance/bank-rules
undocumented /finance/bank-rules
/finance/bank-rules
/finance/budgets
undocumented /finance/budgets
/finance/budgets
/finance/recurring-entries
undocumented /finance/recurring-entries
/finance/recurring-entries
/finance/reports/trial-balance
undocumented /finance/reports/trial-balance
/finance/reports/trial-balance
/finance/reports/income-statement
undocumented /finance/reports/income-statement
/finance/reports/income-statement
/finance/reports/balance-sheet
undocumented /finance/reports/balance-sheet
/finance/reports/balance-sheet
/finance/reports/aged-receivables
undocumented /finance/reports/aged-receivables
/finance/reports/aged-receivables
/finance/reports/aged-payables
undocumented /finance/reports/aged-payables
/finance/reports/aged-payables
/finance/reports/cash-flow
undocumented /finance/reports/cash-flow
/finance/reports/cash-flow
/finance/reports/revenue-by-customer
undocumented /finance/reports/revenue-by-customer
/finance/reports/revenue-by-customer
/finance/reports/budget-vs-actuals
undocumented /finance/reports/budget-vs-actuals
/finance/reports/budget-vs-actuals
/finance/reports/dimensions/:dimension_key
undocumented /finance/reports/dimensions/:dimension_key
dimension_key
string · path
/finance/reports/dimensions/example
/finance/bank-connections/:id/syncs
undocumented /finance/bank-connections/:id/syncs
id
string · path
/finance/bank-connections/example/syncs
/finance/fiscal-periods/:period_id/year-end-close
undocumented /finance/fiscal-periods/:period_id/year-end-close
POST /finance/fiscal-periods/:period_id/year-end-close Posts the closing JE for the fiscal year whose last day matches ``period.end``. No request body — the period alone is the command.
period_id
string · path
/finance/fiscal-periods/example/year-end-close
/finance/recurring-entries/:recurring_id/runs
undocumented /finance/recurring-entries/:recurring_id/runs
Manually trigger a recurring entry — creates a draft invoice or bill. Does NOT advance ``next_date`` or reschedule — that's the scheduled path's job. Manual run is an operator override for off-cycle generation.
recurring_id
string · path
/finance/recurring-entries/example/runs
/finance/settings/logo
undocumented /finance/settings/logo
PUT /finance/settings/logo: replace the logo shown on every document. The object key is generated ONCE and then reused for the life of the workspace, so a replacement overwrites in place. That is deliberate: a new key per upload would orphan the old object and, worse, break the logo in every invoice email already sitting in a customer's inbox. One workspace, one object, one stable URL. The key is flat, extensionless and 128 bits of randomness. Flat and random because the public bucket serves anyone holding the URL, so unguessability is the whole security boundary (listing is disabled, so the key is the only handle). Extensionless because the content type lives in R2 object metadata, which is what browsers, weasyprint and mail clients actually read: keeping an extension would mean a PNG-to-SVG switch silently orphaned the old object. The stored URL carries a ?v= token regenerated on every upload. Overwriting bytes under a cached URL would otherwise keep serving the old logo until the edge TTL lapsed, which reads as a broken save.
/finance/settings/logo
/folders/:folder_id
undocumented /folders/:folder_id
folder_id
string · path
/folders/example
/folders/:folder_id/permissions
undocumented /folders/:folder_id/permissions
folder_id
string · path
/folders/example/permissions
/folders
undocumented /folders
/folders
/folders/:folder_id
undocumented /folders/:folder_id
folder_id
string · path
/folders/example
/folders/:folder_id/files
undocumented /folders/:folder_id/files
folder_id
string · path
/folders/example/files
/folders/:folder_id/permissions
undocumented /folders/:folder_id/permissions
folder_id
string · path
/folders/example/permissions
/folders/:folder_id/archive
undocumented /folders/:folder_id/archive
GET /folders/:folder_id/archive — the folder tree as a ZIP download.
folder_id
string · path
/folders/example/archive
/folders/:folder_id
Update a folder
folder_id
string · path
name
string · min length: 1 · max length: 255
parent_id
string
color
string
is_pinned
propertyName
anything
/folders/example
/folders
Create a folder
name
string · min length: 1 · max length: 255
parent_id
string
color
string
propertyName
anything
/folders
/grants/:id
undocumented /grants/:id
DELETE /grants/:id — revoke a grant. The grant row was loaded + authorized by can_manage_grant_by_id. Ownership grants are not revocable here.
id
string · path
/grants/example
/grants
undocumented /grants
GET /grants?resource_mrn=… — who has access to a record (members + roles, each with their level), plus whether the caller may manage it.
/grants
/grants
Grant access to a record
POST /grants — grant a member or role access to a record. Caps at the read/edit/manage ladder; ownership is never grantable here.
resource_mrn
string · min length: 5 · max length: 255
principal_type
principal_id
string · min length: 1 · max length: 100
action
propertyName
anything
/grants
/growth/campaigns/:id
undocumented /growth/campaigns/:id
Delete a campaign nobody has answered, with its review assignments. One that holds responses or written reviews is closed instead, never deleted.
id
string · path
/growth/campaigns/example
/growth/goals/:id
undocumented /growth/goals/:id
id
string · path
/growth/goals/example
/growth/plans/:id
undocumented /growth/plans/:id
id
string · path
/growth/plans/example
/growth/signals/:id
undocumented /growth/signals/:id
id
string · path
/growth/signals/example
/growth/attributes/:id
undocumented /growth/attributes/:id
id
string · path
/growth/attributes/example
/growth/role-profiles/:id
undocumented /growth/role-profiles/:id
id
string · path
/growth/role-profiles/example
/growth/review-tasks/:id
undocumented /growth/review-tasks/:id
id
string · path
/growth/review-tasks/example
/growth/meeting-series/:id
undocumented /growth/meeting-series/:id
id
string · path
/growth/meeting-series/example
/growth/campaigns
undocumented /growth/campaigns
/growth/campaigns
/growth/campaigns/:id/results
undocumented /growth/campaigns/:id/results
Aggregated, min-group-size-suppressed engagement results for a campaign.
id
string · path
/growth/campaigns/example/results
/growth/goals
undocumented /growth/goals
/growth/goals
/growth/goals/summary
undocumented /growth/goals/summary
/growth/goals/summary
/growth/goals/:id
undocumented /growth/goals/:id
One goal with its key results and its progress log. The goal itself is pre-loaded onto ctx.authz by can_read_goal (rule 18), so this never re-queries it and never re-checks visibility.
id
string · path
/growth/goals/example
/growth/goals/:id/comments
undocumented /growth/goals/:id/comments
The comment thread on a goal, oldest first. Comments are growth_signals rows of kind 'goal_comment' (migration 002). They carry no visibility of their own: reaching this endpoint at all means can_read_goal already decided the caller may see the goal, and a comment is never more private than the goal it sits on.
id
string · path
/growth/goals/example/comments
/growth/plans
undocumented /growth/plans
/growth/plans
/growth/signals
undocumented /growth/signals
/growth/signals
/growth/signals/:id
undocumented /growth/signals/:id
One signal. The full-page 1:1 view loads an interaction through here.
id
string · path
/growth/signals/example
/growth/signals/:id/action-items/tasks
undocumented /growth/signals/:id/action-items/tasks
GET /growth/signals/:id/action-items/tasks — the tasks this 1:1's action items were promoted into, read from the local projection (never from Tasks).
id
string · path
/growth/signals/example/action-items/tasks
/growth/attributes
undocumented /growth/attributes
/growth/attributes
/growth/role-profiles
undocumented /growth/role-profiles
/growth/role-profiles
/growth/role-profiles/:id
undocumented /growth/role-profiles/:id
GET /growth/role-profiles/:id — one career framework, ready to render. Carries the grid, the competencies its rows are drawn from, and the people who sit in the role. Those people come from growth_worker_projection, growth's own projection of workers state (rule 5): matching is on the job title the worker events already carry, so nothing here reaches into the workers app.
id
string · path
/growth/role-profiles/example
/growth/review-tasks
undocumented /growth/review-tasks
/growth/review-tasks
/growth/meeting-series
undocumented /growth/meeting-series
/growth/meeting-series
/growth/skill-matrix
undocumented /growth/skill-matrix
Per-worker competency levels aggregated from structured review ratings. Attributed data, gated to growth.results.view in AUTHZ.
/growth/skill-matrix
/growth/concerns
undocumented /growth/concerns
GET /growth/concerns — the staff triage list: both streams, newest first. Gated to growth.results.view in AUTHZ (same crowd that reads anonymous pulse comments).
/growth/concerns
/growth/overview
undocumented /growth/overview
/growth/overview
/growth/workers
undocumented /growth/workers
The people growth knows as workers, named by their worker record.
/growth/workers
/growth/reports
undocumented /growth/reports
GET /growth/reports: the caller's direct reports, by name.
/growth/reports
/growth/people/:member_id
undocumented /growth/people/:member_id
GET /growth/people/:member_id: who someone is and how the caller relates to them.
member_id
string · path
/growth/people/example
/growth/people
undocumented /growth/people
GET /growth/people?members=mrn,mrn: what the caller may see about each person on one page.
/growth/people
/growth/campaigns
Create a survey
title
string · min length: 1 · max length: 120
kind
frequency
drivers
array
custom_questions
array
question_ids
array
review_kinds
array
enps
comment
starts_at
string
ends_at
string
propertyName
anything
/growth/campaigns
/growth/responses
Submit an anonymous pulse response
Submit an anonymous pulse response. NO identity is stored. ``actor_mrn`` is used ONLY to look up the respondent's coarse segment tags from the projection; it is never written to the response or the emitted event.
campaign_id
string · min length: 1
scores
object
custom_scores
array
enps
integer · min: 0 · max: 10
comment
string · max length: 2000
propertyName
anything
/growth/responses
/growth/responses/:id/replies
Reply to an anonymous comment
Reply to an anonymous comment. The reply is attributed (manager); the respondent stays anonymous. Routed by the opaque response id.
id
string · path
body
string · min length: 1 · max length: 2000
propertyName
anything
/growth/responses/example/replies
/growth/goals
Create a goal, KR or KPI
title
string · min length: 1 · max length: 200
kind
scope
key_results
array
subject_mrn
string · max length: 200
owner_mrn
string · max length: 200
parent_id
string · max length: 80
target
object
metric
string · max length: 120
start_value
number
target_value
number
unit
string · max length: 24
direction
period
string · max length: 40
starts_at
string
due_at
string
propertyName
anything
/growth/goals
/growth/goals/:id/progress
Log goal progress
id
string · path
value
number
note
string · max length: 500
propertyName
anything
/growth/goals/example/progress
/growth/goals/:id/comments
Comment on a goal
Comment on a goal. Anyone who can see the goal can comment on it: this is where blockers get raised, so it is deliberately not gated on can_edit_goal.
id
string · path
text
string · min length: 1 · max length: 4000
propertyName
anything
/growth/goals/example/comments
/growth/plans
Create a development plan or PIP
title
string · min length: 1 · max length: 200
kind
subject_type
subject_mrn
string · max length: 200
owner_mrn
string · max length: 200
reason
string · max length: 4000
detail
object
milestones
array
starts_at
string
ends_at
string
propertyName
anything
/growth/plans
/growth/signals
Give feedback, praise, a 1:1 note or review
kind
subject_mrn
string · max length: 200
campaign_id
string · max length: 80
parent_id
string · max length: 80
series_id
string · max length: 80
visibility
body
object
title
string · max length: 200
text
string · max length: 8000
values
array
competencies
array
competency_ratings
array
agenda
array
action_items
array
check_in_items
array
private_note
string · max length: 8000
rating
number · min: 0 · max: 5
occurred_at
string
propertyName
anything
/growth/signals
/growth/signals/:id/action-items/:index/task
Turn a 1:1 action item into a task
POST /growth/signals/:id/action-items/:index/task — make this action item a real task. Growth never calls the Tasks API (rule 6): it emits, Tasks creates, and the resulting core.tasks.task.created comes back round the bus into growth_task_projection. So this answers 202, not 201 — the task does not exist yet when we reply.
id
string · path
index
string · path
board_id
string · min length: 1
propertyName
anything
/growth/signals/example/action-items/example/task
/growth/attributes
Create a competency, value or bank question
kind
name
string · min length: 1 · max length: 120
description
string · max length: 2000
category
string · max length: 80
levels
array
driver
scale
integer · min: 2 · max: 10
sort
integer · min: 0 · max: 999
propertyName
anything
/growth/attributes
/growth/role-profiles
Create a role profile
title
string · min length: 1 · max length: 120
track
string · max length: 80
level
string · max length: 40
description
string · max length: 2000
expectations
array
job_titles
array
propertyName
anything
/growth/role-profiles
/growth/review-tasks
Nominate a peer or upward reviewer
Peer / upward nomination. Self and manager tasks come from cycle launch.
campaign_id
string · min length: 1 · max length: 80
kind
reviewer_mrn
string · min length: 1 · max length: 200
subject_mrn
string · max length: 200
due_at
string
propertyName
anything
/growth/review-tasks
/growth/meeting-series
Start a recurring 1:1
participant_mrn
string · min length: 1 · max length: 200
title
string · max length: 120
cadence
next_at
string
agenda
array
propertyName
anything
/growth/meeting-series
/growth/concerns
Raise a concern, anonymously or named
POST /growth/concerns — file a concern, anonymously or named. Anonymous: actor_mrn is used ONLY to derive coarse segment tags (exactly like a pulse response); no identity is stored on the row or the event. Named: a complaint signal authored by the caller, visible to managers/HR.
body
string · min length: 1 · max length: 4000
anonymous
propertyName
anything
/growth/concerns
/growth/campaigns/:id
Update or launch a survey
id
string · path
title
string · min length: 1 · max length: 120
status
frequency
drivers
array
custom_questions
array
question_ids
array
review_kinds
array
enps
comment
starts_at
string
ends_at
string
propertyName
anything
/growth/campaigns/example
/growth/goals/:id
Update a goal
id
string · path
title
string · min length: 1 · max length: 200
status
owner_mrn
string · max length: 200
parent_id
string · max length: 80
target
object
period
string · max length: 40
due_at
string
propertyName
anything
/growth/goals/example
/growth/plans/:id
Update a plan
id
string · path
title
string · min length: 1 · max length: 200
status
owner_mrn
string · max length: 200
reason
string · max length: 4000
detail
object
starts_at
string
ends_at
string
propertyName
anything
/growth/plans/example
/growth/signals/:id
Update a signal
id
string · path
visibility
body
object
rating
number · min: 0 · max: 5
status
series_id
string · max length: 80
private_note
string · max length: 8000
propertyName
anything
/growth/signals/example
/growth/attributes/:id
Update a competency, value or question
id
string · path
name
string · min length: 1 · max length: 120
description
string · max length: 2000
category
string · max length: 80
levels
array
driver
scale
integer · min: 2 · max: 10
sort
integer · min: 0 · max: 999
status
propertyName
anything
/growth/attributes/example
/growth/role-profiles/:id
Update a role profile
id
string · path
title
string · min length: 1 · max length: 120
track
string · max length: 80
level
string · max length: 40
description
string · max length: 2000
expectations
array
job_titles
array
matrix
object
status
propertyName
anything
/growth/role-profiles/example
/growth/review-tasks/:id
Update a review task
id
string · path
status
due_at
string
extension_until
string
extension_note
string · max length: 500
extension
propertyName
anything
/growth/review-tasks/example
/growth/meeting-series/:id
Update a 1:1 series
id
string · path
title
string · max length: 120
cadence
next_at
string
agenda
array
status
propertyName
anything
/growth/meeting-series/example
/health
undocumented /health
/health
/holidays/:id
undocumented /holidays/:id
id
string · path
/holidays/example
/holidays
undocumented /holidays
/holidays
/holidays
Create a holiday
name
string · min length: 1 · max length: 100
date
string · min length: 1
is_recurring
propertyName
anything
/holidays
/holidays/:id
Update a holiday
id
string · path
name
string · min length: 1 · max length: 100
date
string · min length: 1
is_recurring
propertyName
anything
/holidays/example
/hub/posts/:id
undocumented /hub/posts/:id
DELETE /hub/posts/:id: the author, or an owner or admin.
id
string · path
/hub/posts/example
/hub/posts/:id/reactions
undocumented /hub/posts/:id/reactions
DELETE /hub/posts/:id/reactions: take yours back.
id
string · path
/hub/posts/example/reactions
/hub/posts/:id/reposts
undocumented /hub/posts/:id/reposts
DELETE /hub/posts/:id/reposts: undo your plain repost of this post.
id
string · path
/hub/posts/example/reposts
/hub/posts/:id/votes
undocumented /hub/posts/:id/votes
DELETE /hub/posts/:id/votes: take your vote back.
id
string · path
/hub/posts/example/votes
/hub/posts/:id/bookmarks
undocumented /hub/posts/:id/bookmarks
DELETE /hub/posts/:id/bookmarks
id
string · path
/hub/posts/example/bookmarks
/hub/circles/:id/members
undocumented /hub/circles/:id/members
DELETE /hub/circles/:id/members: leave.
id
string · path
/hub/circles/example/members
/hub/follows/:target_mrn
undocumented /hub/follows/:target_mrn
DELETE /hub/follows/:target_mrn (the MRN may arrive URL-encoded).
target_mrn
string · path
/hub/follows/example
/hub/posts
undocumented /hub/posts
GET /hub/posts?feed=everyone|following|circle&circle_id=&author= : newest first.
/hub/posts
/hub/posts/:id
undocumented /hub/posts/:id
GET /hub/posts/:id
id
string · path
/hub/posts/example
/hub/posts/:id/replies
undocumented /hub/posts/:id/replies
GET /hub/posts/:id/replies: oldest first.
id
string · path
/hub/posts/example/replies
/hub/bookmarks
undocumented /hub/bookmarks
GET /hub/bookmarks: what you saved, most recent first.
/hub/bookmarks
/hub/events
undocumented /hub/events
GET /hub/events: events posted in the Hub that have not happened yet, soonest first.
/hub/events
/hub/circles
undocumented /hub/circles
GET /hub/circles: every circle, the ones you joined first.
/hub/circles
/hub/follows
undocumented /hub/follows
GET /hub/follows: who you follow.
/hub/follows
/hub/posts
Post to the Hub
POST /hub/posts: words, media, and optionally a circle, a poll or an event.
content
string · max length: 5000
media
array
circle_id
string · min length: 1 · max length: 64
poll
object
event
object
propertyName
anything
/hub/posts
/hub/posts/:id/replies
Reply to a post
POST /hub/posts/:id/replies
id
string · path
content
string · max length: 5000
media
array
propertyName
anything
/hub/posts/example/replies
/hub/posts/:id/reactions
React to a post
POST /hub/posts/:id/reactions {reaction_type}: add yours, or change it.
id
string · path
reaction_type
propertyName
anything
/hub/posts/example/reactions
/hub/posts/:id/reposts
Repost or quote a post
POST /hub/posts/:id/reposts {content?}: a plain repost, or a quote when there are words.
id
string · path
content
string · max length: 5000
propertyName
anything
/hub/posts/example/reposts
/hub/posts/:id/votes
Vote in a poll
POST /hub/posts/:id/votes {option_id}: your one vote; voting again moves it.
id
string · path
option_id
string · min length: 1 · max length: 64
propertyName
anything
/hub/posts/example/votes
/hub/posts/:id/bookmarks
undocumented /hub/posts/:id/bookmarks
POST /hub/posts/:id/bookmarks
id
string · path
/hub/posts/example/bookmarks
/hub/circles
Start a circle
POST /hub/circles {name, description?}: you start it and are its first member.
name
string · min length: 1 · max length: 60
description
string · max length: 300
propertyName
anything
/hub/circles
/hub/circles/:id/members
undocumented /hub/circles/:id/members
POST /hub/circles/:id/members: join.
id
string · path
/hub/circles/example/members
/hub/follows
Follow a member
POST /hub/follows {target_mrn}
target_mrn
string · min length: 1 · max length: 120
propertyName
anything
/hub/follows
/hub/posts/:id/rsvp
Say if you're going to an event
PUT /hub/posts/:id/rsvp {status}: going, maybe or not going.
id
string · path
status
propertyName
anything
/hub/posts/example/rsvp
/installations/:slug
undocumented /installations/:slug
DELETE /installations/:slug — Uninstall an app (admin/owner only).
slug
string · path
/installations/example
/installations
undocumented /installations
GET /installations — List installed apps for the workspace. Default view returns apps the current member can access (UI grid). Pass ?policy=1 (owner/admin only) to include access_policy + allowed_roles for every installed app — used by the App Access admin screen.
/installations
/interactions/:interaction_id
undocumented /interactions/:interaction_id
DELETE /interactions/:interaction_id — delete an interaction.
interaction_id
string · path
/interactions/example
/interactions
undocumented /interactions
GET /interactions — all interactions (activity reports).
/interactions
/interactions
Log an interaction
POST /interactions — log an interaction.
contact_id
string
company_id
string
source_mrn
string
type
direction
subject
string · max length: 200
content
string · max length: 10000
occurred_at
string
duration_minutes
integer
rating
object
propertyName
anything
/interactions
/interactions/:interaction_id
Update an interaction
PUT /interactions/:interaction_id — update an interaction.
interaction_id
string · path
subject
string · max length: 200
content
string · max length: 10000
occurred_at
string
duration_minutes
integer
propertyName
anything
/interactions/example
/invoices/:id
undocumented /invoices/:id
GET /invoices/:id — return full invoice data with line items.
id
string · path
/invoices/example
/finance/invoices/:entry_id
Issue/void an invoice
entry_id
string · path
status
propertyName
anything
/finance/invoices/example
/finance/invoices
Create an invoice
date
string · min length: 10
items
array
contact_mrn
string
company_mrn
string
currency
exchange_rate
number
due_date
string · min length: 10
memo
string · max length: 5000
tags
array
sources
array
adjustments
array
dimensions
idempotency_key
string · max length: 100
propertyName
anything
/finance/invoices
/finance/invoices/:entry_id/pdfs
Generate invoice PDF
entry_id
string · path
template
string · max length: 100
propertyName
anything
/finance/invoices/example/pdfs
/finance/invoices/:entry_id/sends
Email an invoice
entry_id
string · path
to
string · min length: 1 · max length: 500
cc
string · max length: 500
subject
string · max length: 300
message
string · max length: 5000
attach_pdf
propertyName
anything
/finance/invoices/example/sends
/finance/invoices/:entry_id/reminders
Send an overdue reminder
entry_id
string · path
to
string · min length: 1 · max length: 500
subject
string · max length: 300
message
string · max length: 5000
propertyName
anything
/finance/invoices/example/reminders
/invoices/:id/charges
undocumented /invoices/:id/charges
POST /invoices/:id/charges — retry charging the default payment method.
id
string · path
/invoices/example/charges
/finance/invoices/:entry_id
Update a draft invoice
entry_id
string · path
date
string · min length: 10
items
array
contact_mrn
string
company_mrn
string
currency
exchange_rate
number
due_date
string · min length: 10
memo
string · max length: 5000
tags
array
adjustments
array
dimensions
propertyName
anything
/finance/invoices/example
/finance/journal-entries/:entry_id
Post/void a journal
entry_id
string · path
status
propertyName
anything
/finance/journal-entries/example
/finance/journal-entries
Create a journal entry
date
string · min length: 10
lines
array
memo
string · max length: 5000
currency
exchange_rate
number
tags
array
dimensions
idempotency_key
string · max length: 100
propertyName
anything
/finance/journal-entries
/finance/journal-entries/:entry_id
Update a draft journal
entry_id
string · path
date
string · min length: 10
lines
array
memo
string · max length: 5000
currency
exchange_rate
number
tags
array
dimensions
propertyName
anything
/finance/journal-entries/example
/leave-balances/:id/adjustments
Adjust a leave balance
Manual balance adjustment (admin only).
id
string · path
amount
number
reason
string · min length: 1 · max length: 500
propertyName
anything
/leave-balances/example/adjustments
/leave-policies/:id/members
Remove workers from a leave policy
DELETE /leave-policies/:id/members: take a selection of workers off a policy. Anyone with a pending request on the policy stays on it and is reported as kept.
id
string · path
worker_mrns
array
match
object
exclude_worker_mrns
array
propertyName
anything
/leave-policies/example/members
/leave-policies
Create a leave policy
name
string · min length: 1 · max length: 100
type
allowance
number
description
string · max length: 500
accrual
max_carry_over
number
requires_approval
min_notice_days
integer
max_consecutive_days
integer
applies_to
cycle_start
default_approver_mrns
array
propertyName
anything
/leave-policies
/leave-policies/:id/members
Assign workers to a leave policy
POST /leave-policies/:id/members — Assign workers to a policy and provision balances.
id
string · path
worker_mrns
array
match
object
exclude_worker_mrns
array
propertyName
anything
/leave-policies/example/members
/leave-policies/:id
Update a leave policy
id
string · path
name
string · min length: 1 · max length: 100
description
string · max length: 500
allowance
number
accrual
max_carry_over
number
requires_approval
min_notice_days
integer
max_consecutive_days
integer
applies_to
cycle_start
is_active
default_approver_mrns
array
propertyName
anything
/leave-policies/example
/leave-balances
undocumented /leave-balances
List balances for the current user's worker record. Self view: only balances for policies the worker is currently assigned to. Orphan rows (pre-membership provisioning, or kept after unassignment because days were used) stay in the table for history but are not returned here; the manager view (GET /leave-balances/:worker_mrn) still exposes them.
/leave-balances
/leave-balances/:worker_mrn
undocumented /leave-balances/:worker_mrn
List balances for a specific worker (manager/admin).
worker_mrn
string · path
/leave-balances/example
/leave-calculate-days
undocumented /leave-calculate-days
Calculate working days between two dates.
/leave-calculate-days
/leave-calendar
undocumented /leave-calendar
Team calendar — approved PTOs + holidays for a date range.
/leave-calendar
/leave-policies/:id
undocumented /leave-policies/:id
id
string · path
/leave-policies/example
/leave-policies/:id/members/:worker_mrn
undocumented /leave-policies/:id/members/:worker_mrn
DELETE /leave-policies/:id/members/:worker_mrn — Remove a worker from a policy.
id
string · path
worker_mrn
string · path
/leave-policies/example/members/example
/leave-policies
undocumented /leave-policies
/leave-policies
/leave-policies/:id
undocumented /leave-policies/:id
id
string · path
/leave-policies/example
/leave-policies/:id/members
undocumented /leave-policies/:id/members
GET /leave-policies/:id/members — List workers assigned to a policy.
id
string · path
/leave-policies/example/members
/leave-policies/:id/candidates
undocumented /leave-policies/:id/candidates
GET /leave-policies/:id/candidates: active workers not on the policy who match a search and filters.
id
string · path
/leave-policies/example/candidates
/leave-policies/:id/worker-filters
undocumented /leave-policies/:id/worker-filters
GET /leave-policies/:id/worker-filters: the fields a policy's worker lists can be filtered by.
id
string · path
/leave-policies/example/worker-filters
/leave-policies/:id/worker-filters/:key/options
undocumented /leave-policies/:id/worker-filters/:key/options
GET /leave-policies/:id/worker-filters/:key/options: one field's values, every one in the workspace, or with scope=members only those held by the workers on the policy.
id
string · path
key
string · path
/leave-policies/example/worker-filters/example/options
/leave-reconciliation
undocumented /leave-reconciliation
GET /leave-reconciliation — future bookings whose day count changed under the current working pattern, with a read-only entitlement pro-ration hint.
/leave-reconciliation
/leave-reconciliation
undocumented /leave-reconciliation
POST /leave-reconciliation — recount every affected future booking and adjust its balance (admin sign-off). Past/in-progress untouched; approved bookings re-emit so the attendance projection rebuilds on the new pattern. Entitlement pro-ration is NOT done here — it's a separate audited adjustment.
/leave-reconciliation
/calls/:id/links/:link_id
Update a join link
id
string · path
link_id
string · path
is_active
external_join_mode
propertyName
anything
/calls/example/links/example
/calls/:id/links
Create a join link
id
string · path
expires_at
string
guest_name
string · max length: 200
guest_email
string · max length: 200
external_join_mode
propertyName
anything
/calls/example/links
/chats/lists/:list_id
Update a chat list
PATCH /chats/lists/:list_id — rename or reorder a list.
list_id
string · path
name
string · min length: 1 · max length: 50
position
integer
propertyName
anything
/chats/lists/example
/chats/lists
Create a chat list
POST /chats/lists — create a personal chat list.
name
string · min length: 1 · max length: 50
chat_ids
array
propertyName
anything
/chats/lists
/wands/macro-previews
Try a single macro against a sample event
Run a single macro against a sample event and return what it produced. The teaching sandbox behind the macro reference page. Reads run for real with the viewer's own permissions; anything that writes is simulated (dry_run is forced server-side and is not caller-controllable).
macro
string · min length: 2 · max length: 40
args
payload
event_name
string · max length: 200
propertyName
anything
/wands/macro-previews
/mail/accounts/:account_id
undocumented /mail/accounts/:account_id
account_id
string · path
/mail/accounts/example
/mail/accounts/:account_id/messages/:message_id
undocumented /mail/accounts/:account_id/messages/:message_id
account_id
string · path
message_id
string · path
/mail/accounts/example/messages/example
/mail/accounts/:account_id/signatures/:signature_id
undocumented /mail/accounts/:account_id/signatures/:signature_id
account_id
string · path
signature_id
string · path
/mail/accounts/example/signatures/example
/mail/accounts/:account_id/filters/:filter_id
undocumented /mail/accounts/:account_id/filters/:filter_id
account_id
string · path
filter_id
string · path
/mail/accounts/example/filters/example
/mail/accounts/:account_id/blocked-senders/:blocked_id
undocumented /mail/accounts/:account_id/blocked-senders/:blocked_id
account_id
string · path
blocked_id
string · path
/mail/accounts/example/blocked-senders/example
/mail/domains/:domain_id
undocumented /mail/domains/:domain_id
Remove a domain (pending typo or live). Cleans the MX box (virtual domain + DKIM, cascading its mailboxes) best-effort, then removes the platform rows. A domain exists on the mail server and the relay only once its ownership was proved, and is never taken off them when another workspace has verified it (core/mail/domains.py remove_from_mail_systems). A pending row removes cleanly and touches nothing outside this workspace.
domain_id
string · path
/mail/domains/example
/mail/mailboxes/:mailbox_id
undocumented /mail/mailboxes/:mailbox_id
mailbox_id
string · path
/mail/mailboxes/example
/mail/groups/:group_id
undocumented /mail/groups/:group_id
Remove a shared mailbox, its aliases and its backing mailbox.
group_id
string · path
/mail/groups/example
/mail/groups/:group_id/members/:member_id
undocumented /mail/groups/:group_id/members/:member_id
group_id
string · path
member_id
string · path
/mail/groups/example/members/example
/mail/groups/:group_id/messages/:message_id
undocumented /mail/groups/:group_id/messages/:message_id
group_id
string · path
message_id
string · path
/mail/groups/example/messages/example
/mail/drafts/:draft_id
undocumented /mail/drafts/:draft_id
draft_id
string · path
/mail/drafts/example
/mail/mailboxes/:mailbox_id/outbox-keys/:key_id
undocumented /mail/mailboxes/:mailbox_id/outbox-keys/:key_id
Remove the audit row — only after revoke, same as API keys.
mailbox_id
string · path
key_id
string · path
/mail/mailboxes/example/outbox-keys/example
/mail/oauth/:provider/authorize
undocumented /mail/oauth/:provider/authorize
provider
string · path
/mail/oauth/example/authorize
/mail/oauth/:provider/callback
undocumented /mail/oauth/:provider/callback
provider
string · path
/mail/oauth/example/callback
/mail/accounts
undocumented /mail/accounts
GET /mail/accounts: this member's connected accounts. Each row carries ``consumer_reason``, which is empty for every account that is fine and carries the explanation for one that is not. Accounts connected before the consumer-domain rule existed keep their rows and their history: deleting them would take somebody's mail away to enforce a rule made after they connected. They stop syncing and say why instead.
/mail/accounts
/mail/recipients
undocumented /mail/recipients
Typeahead source for the compose recipient fields: workspace members who have been assigned a mail account (their own mailbox, or a connected Google Workspace or Microsoft 365 account). The contacts directory — people already emailed or received from — is merged client-side from the contacts app, so mail never reads another app's tables (rule 6).
/mail/recipients
/mail/unified/messages
undocumented /mail/unified/messages
One folder across the member's unified accounts and shared inboxes, newest first, paged.
/mail/unified/messages
/mail/accounts/:account_id/messages
undocumented /mail/accounts/:account_id/messages
account_id
string · path
/mail/accounts/example/messages
/mail/accounts/:account_id/messages/:message_id
undocumented /mail/accounts/:account_id/messages/:message_id
account_id
string · path
message_id
string · path
/mail/accounts/example/messages/example
/mail/accounts/:account_id/messages/:message_id/attachments/:index
undocumented /mail/accounts/:account_id/messages/:message_id/attachments/:index
Stream one attachment of a message as a download. Bytes live only in the IMAP message (not our storage), so they're fetched from the provider on demand.
account_id
string · path
message_id
string · path
index
string · path
/mail/accounts/example/messages/example/attachments/example
/mail/accounts/:account_id/messages/:message_id/calendar
undocumented /mail/accounts/:account_id/messages/:message_id/calendar
Parse the calendar invite(s) (.ics) attached to a message into platform-calendar event fields, so the client can add them via POST /meetings. Attachment bytes are only fetched from Saasmail (MX) inboxes — the same limitation as attachment download.
account_id
string · path
message_id
string · path
/mail/accounts/example/messages/example/calendar
/mail/accounts/:account_id/folders
undocumented /mail/accounts/:account_id/folders
account_id
string · path
/mail/accounts/example/folders
/mail/accounts/:account_id/signatures
undocumented /mail/accounts/:account_id/signatures
account_id
string · path
/mail/accounts/example/signatures
/mail/accounts/:account_id/filters
undocumented /mail/accounts/:account_id/filters
account_id
string · path
/mail/accounts/example/filters
/mail/accounts/:account_id/blocked-senders
undocumented /mail/accounts/:account_id/blocked-senders
account_id
string · path
/mail/accounts/example/blocked-senders
/mail/domains
undocumented /mail/domains
/mail/domains
/mail/domains/:domain_id/dmarc
undocumented /mail/domains/:domain_id/dmarc
GET /mail/domains/:domain_id/dmarc: senders failing DMARC for this domain this week.
domain_id
string · path
/mail/domains/example/dmarc
/mail/mailboxes
undocumented /mail/mailboxes
/mail/mailboxes
/mail/imports
undocumented /mail/imports
/mail/imports
/mail/imports/:import_id
undocumented /mail/imports/:import_id
import_id
string · path
/mail/imports/example
/mail/groups
undocumented /mail/groups
/mail/groups
/mail/groups/:group_id/members
undocumented /mail/groups/:group_id/members
group_id
string · path
/mail/groups/example/members
/mail/groups/:group_id/drafts
undocumented /mail/groups/:group_id/drafts
In-progress (unsent) drafts for a group — co-editors open these to edit together. Reply tier required: read-only members don't see drafts still being composed.
group_id
string · path
/mail/groups/example/drafts
/mail/groups/:group_id/thread
undocumented /mail/groups/:group_id/thread
The group conversation — sent drafts in order, each showing who sent it.
group_id
string · path
/mail/groups/example/thread
/mail/groups/:group_id/messages
undocumented /mail/groups/:group_id/messages
group_id
string · path
/mail/groups/example/messages
/mail/groups/:group_id/messages/:message_id
undocumented /mail/groups/:group_id/messages/:message_id
group_id
string · path
message_id
string · path
/mail/groups/example/messages/example
/mail/groups/:group_id/messages/:message_id/attachments/:index
undocumented /mail/groups/:group_id/messages/:message_id/attachments/:index
group_id
string · path
message_id
string · path
index
string · path
/mail/groups/example/messages/example/attachments/example
/mail/groups/:group_id/messages/:message_id/calendar
undocumented /mail/groups/:group_id/messages/:message_id/calendar
Parse the calendar invite(s) (.ics) attached to a shared-inbox message into platform-calendar event fields (same as the personal-account endpoint).
group_id
string · path
message_id
string · path
/mail/groups/example/messages/example/calendar
/mail/drafts
undocumented /mail/drafts
The member's own personal (non-group) unsent drafts, newest first.
/mail/drafts
/mail/mailboxes/:mailbox_id/outbox-keys
undocumented /mail/mailboxes/:mailbox_id/outbox-keys
List a mailbox's outbox keys (prefix, name, status, last used) — never the secret. 404 for a caller who fails the mint-identity gate.
mailbox_id
string · path
/mail/mailboxes/example/outbox-keys
/mail/accounts/:account_id
Update mail account
account_id
string · path
display_name
string · max length: 200
show_in_unified
propertyName
anything
/mail/accounts/example
/mail/accounts/:account_id/messages/:message_id
Modify a message
account_id
string · path
message_id
string · path
is_read
is_starred
folder
string · min length: 1 · max length: 100
propertyName
anything
/mail/accounts/example/messages/example
/mail/groups/:group_id
undocumented /mail/groups/:group_id
Cosmetic group settings. Any member may set the shared inbox's badge color; only admins may rename it.
group_id
string · path
/mail/groups/example
/mail/groups/:group_id/messages/:message_id
Modify a shared-inbox message
group_id
string · path
message_id
string · path
is_read
is_starred
folder
string · min length: 1 · max length: 100
propertyName
anything
/mail/groups/example/messages/example
/mail/accounts/:account_id/messages
Send a message
account_id
string · path
to
array
cc
array
bcc
array
subject
string · max length: 998
body_text
string
body_html
string
is_draft
signature_id
string · min length: 1
attachments
array
in_reply_to
string · max length: 998
references
string · max length: 8000
propertyName
anything
/mail/accounts/example/messages
/mail/accounts/:account_id/signatures
Create signature
account_id
string · path
name
string · min length: 1 · max length: 100
body_html
string · max length: 40000
is_default
propertyName
anything
/mail/accounts/example/signatures
/mail/accounts/:account_id/images
undocumented /mail/accounts/:account_id/images
POST an image for a signature or a composed message. Public on purpose, because a recipient's mail client fetches it with no account.
account_id
string · path
/mail/accounts/example/images
/mail/accounts/:account_id/filters
Create filter
account_id
string · path
name
string · min length: 1 · max length: 200
conditions
object
actions
object
propertyName
anything
/mail/accounts/example/filters
/mail/accounts/:account_id/blocked-senders
Block a sender
account_id
string · path
blocked
string · min length: 3 · max length: 254
propertyName
anything
/mail/accounts/example/blocked-senders
/mail/domains/:domain_id/verifications
undocumented /mail/domains/:domain_id/verifications
Check DNS for the ownership token (+ the mail records). Only marks the domain verified/usable once the ownership TXT resolves.
domain_id
string · path
/mail/domains/example/verifications
/mail/drafts
Create draft
subject
string · max length: 998
body_html
string
recipients
object
attachments
array
group_id
string · min length: 1 · max length: 64
account_id
string · min length: 1 · max length: 64
in_reply_to
string · max length: 998
references
string · max length: 8000
quoted_html
string
propertyName
anything
/mail/drafts
/mail/drafts/:draft_id/send
Send draft
draft_id
string · path
subject
string · max length: 998
body_html
string
recipients
object
propertyName
anything
/mail/drafts/example/send
/mail/accounts/:account_id/signatures/:signature_id
Update signature
account_id
string · path
signature_id
string · path
name
string · min length: 1 · max length: 100
body_html
string · max length: 40000
is_default
propertyName
anything
/mail/accounts/example/signatures/example
/mail/drafts/:draft_id
Save draft
draft_id
string · path
subject
string · max length: 998
body_html
string
recipients
object
attachments
array
group_id
string · min length: 1 · max length: 64
account_id
string · min length: 1 · max length: 64
in_reply_to
string · max length: 998
references
string · max length: 8000
quoted_html
string
propertyName
anything
/mail/drafts/example
/mail/mailboxes/:mailbox_id/outbox-keys/:key_id/secret
undocumented /mail/mailboxes/:mailbox_id/outbox-keys/:key_id/secret
Replace the secret; the old one dies now. New secret shown once.
mailbox_id
string · path
key_id
string · path
/mail/mailboxes/example/outbox-keys/example/secret
/exchanges
Send mail as a hosted mailbox
Send as a hosted mailbox. authz_exchange_send already passed the slk_ (steps 1-3 of the auth order); this handler runs steps 4-6 — the outbox key must hash to a live key on an active MX mailbox in this workspace — then validates the body, applies limits and idempotency, and submits through the existing MX path (postfix :587 as the mailbox, copy in Sent).
to
array
cc
array
bcc
array
subject
string · max length: 998
html
string
text
string
from_name
string · max length: 200
reply_to
string · max length: 254 · email
attachments
array
in_reply_to
string · max length: 998
references
string · max length: 8000
propertyName
anything
/exchanges
/mail/mailboxes/:mailbox_id/outbox-keys
Mint an outbox key
Mint a named key for this shared mailbox. The secret appears in this response only; the row stores its sha256. kind is always 'shared' now (personal mailboxes have no keys) and the send path re-checks it.
mailbox_id
string · path
name
string · min length: 1 · max length: 100
expires_at
string · max length: 64
propertyName
anything
/mail/mailboxes/example/outbox-keys
/mail/mailboxes/:mailbox_id/outbox-keys/:key_id
Rename or revoke an outbox key
Rename and/or revoke a key. Revocation is soft and takes effect on the key's next send; the row stays as an audit record until deleted.
mailbox_id
string · path
key_id
string · path
name
string · min length: 1 · max length: 100
status
string
propertyName
anything
/mail/mailboxes/example/outbox-keys/example
/mail/domains/:domain_id
Set domain catch-all
Set/clear the wildcard catch-all address for a domain.
domain_id
string · path
catch_all_to
string · max length: 254
propertyName
anything
/mail/domains/example
/mail/mailboxes/:mailbox_id
Assign a mailbox to a member
Assign (or unassign, with an empty member_mrn) a provisioned mailbox to a member. Keeps the member's connected-accounts mirror in sync so it appears in their client.
mailbox_id
string · path
member_mrn
string · max length: 200
propertyName
anything
/mail/mailboxes/example
/mail/groups/:group_id/members/:member_id
Change member tier
Change an assignee's content-permission tier. Admins only — membership and tier assignment are group configuration, not a content capability.
group_id
string · path
member_id
string · path
role
string
propertyName
anything
/mail/groups/example/members/example
/mail/domains
Add a mail domain
Register a domain as PENDING and return the DNS to publish. Nothing is activated and no DNS is written on the owner's behalf — they publish the records, then verify.
domain
string · min length: 3 · max length: 253
propertyName
anything
/mail/domains
/mail/mailboxes
Provision a mailbox
local_part
string · min length: 1 · max length: 64
member_mrn
string · max length: 200
display_name
string · max length: 200
quota_mb
integer · min: 10 · max: 51200
propertyName
anything
/mail/mailboxes
/mail/mailboxes/bulk
Provision many mailboxes
Create many addresses on one verified domain at once (editable grid / CSV upload). Each row is validated and provisioned independently: a malformed local-part or an address that already exists is reported back under `skipped` (with a reason) while the rest are still created — partial success, never an all-or-nothing batch.
domain_id
string · min length: 1 · max length: 64
mailboxes
array
propertyName
anything
/mail/mailboxes/bulk
/mail/imports
Import an exported mailbox
mailbox_id
string · min length: 1 · max length: 64
storage_key
string · min length: 1 · max length: 1024
filename
string · min length: 1 · max length: 255
propertyName
anything
/mail/imports
/mail/groups
Create group mailbox
name
string · min length: 1 · max length: 120
local_part
string · min length: 1 · max length: 64
domain_id
string · min length: 1 · max length: 64
aliases
array
member_mrns
array
propertyName
anything
/mail/groups
/mail/groups/:group_id/members
Add group member
group_id
string · path
member_mrn
string · min length: 1 · max length: 200
role
string
propertyName
anything
/mail/groups/example/members
/demo-requests
Request a demo
POST /demo-requests — public lead capture for "Book a demo" (no auth).
name
string · min length: 1 · max length: 120
work_email
string · min length: 1 · email
slot
string · min length: 1 · max length: 40
company
string · max length: 200
team_size
string · max length: 40
message
string · max length: 1000
timezone
string · max length: 64
website
string · max length: 200
propertyName
anything
/demo-requests
/me
undocumented /me
/me
/me/notification-preferences
undocumented /me/notification-preferences
/me/notification-preferences
/media/:collection
undocumented /media/:collection
GET /media/:collection — trending by default, search when ?q= is set.
collection
string · path
/media/example
/media/:collection/categories
undocumented /media/:collection/categories
GET /media/:collection/categories — the suggestion chips above the grid.
collection
string · path
/media/example/categories
/media/:collection/shares
Record that a media item was used
POST /media/:collection/shares — record that an item was used. KLIPY builds its trending ranking from this, and firing it is what an integration owes them for the catalogue. Called once the item has actually landed in a message or on a slide, never on hover or on a grid render. A failure here is deliberately not the caller's problem: the GIF is already sent. The response is 204 either way and the client never waits on it.
collection
string · path
slug
string · min length: 1 · max length: 200
propertyName
anything
/media/example/shares
/meetings/:id
undocumented /meetings/:id
id
string · path
/meetings/example
/meetings/:id/attendees/:attendee_id
undocumented /meetings/:id/attendees/:attendee_id
id
string · path
attendee_id
string · path
/meetings/example/attendees/example
/meetings
undocumented /meetings
/meetings
/meetings/:id/attendees
undocumented /meetings/:id/attendees
id
string · path
/meetings/example/attendees
/meetings/:id
Update a meeting
id
string · path
title
string · min length: 1 · max length: 300
description
string
start_datetime
string
end_datetime
string
timezone
string · max length: 64
is_all_day
color
string
type
string
status
string
recurrence_rule
string
visibility
string
propertyName
anything
/meetings/example
/meetings
Create a meeting
title
string · min length: 1 · max length: 300
start_datetime
string · min length: 1
end_datetime
string · min length: 1
description
string
timezone
string · max length: 64
is_all_day
color
string
type
string
status
string
create_call
recurrence_rule
string
visibility
string
attendees
array
external_invitees
array
propertyName
anything
/meetings
/meetings/:id/attendees
Add someone to a meeting
id
string · path
profile_id
string · max length: 100
email
string · max length: 320
name
string · max length: 200
notify_everyone
propertyName
anything
/meetings/example/attendees
/meetings/:id/call
undocumented /meetings/:id/call
id
string · path
/meetings/example/call
/meetings/:id/rsvp
Set your RSVP for a meeting
PUT /meetings/:id/rsvp — the authenticated caller sets their own RSVP.
id
string · path
status
propertyName
anything
/meetings/example/rsvp
/members/:member_id
undocumented /members/:member_id
DELETE /accounts/organisation/members/:member_id — Remove a member.
member_id
string · path
/members/example
/members
undocumented /members
GET /members — Search workspace members by name or email.
/members
/members/:member_id
undocumented /members/:member_id
PATCH /accounts/organisation/members/:member_id — Change platform role.
member_id
string · path
/members/example
/members
Invite member
POST /accounts/organisation/members — Invite a member.
email
string · min length: 1 · email
full_name
string · max length: 200
role
propertyName
anything
/members
/members/bulk
Bulk invite members
POST /members/bulk — Invite multiple members at once.
members
array
propertyName
anything
/members/bulk
/members/:member_id/invitations
undocumented /members/:member_id/invitations
POST /members/:member_id/invitations — Re-invite a member with a fresh token.
member_id
string · path
/members/example/invitations
/members/:member_id/password-resets
undocumented /members/:member_id/password-resets
POST /members/:member_id/password-resets — Send a 'Set Your Password' email.
member_id
string · path
/members/example/password-resets
/members/:member_id/sessions
Force logout member
POST /members/:member_id/sessions — really sign a member out of THIS workspace. This used to push a WebSocket frame and hope the browser was listening, which a closed tab, an offline client, or anyone holding the cookie in curl simply ignored. Then it rotated the profile's security stamp, which worked but was per IDENTITY: the same person signed into another workspace under the same email got kicked out of that one too, by an admin with no authority there. Since migration 079 every session has its own row tagged with the workspace it belongs to, so this revokes exactly the rows for this workspace. The socket push stays as the courtesy, not the mechanism.
member_id
string · path
action
propertyName
anything
/members/example/sessions
/chats/:id/messages/:msg_id
Edit a message
PATCH /chats/:id/messages/:msg_id — edit a message.
id
string · path
msg_id
string · path
content
string · min length: 1 · max length: 10000
propertyName
anything
/chats/example/messages/example
/calls/:id/messages
Send a chat message
id
string · path
content
string · min length: 1 · max length: 2000
propertyName
anything
/calls/example/messages
/chats/:id/messages
Send a message
POST /chats/:id/messages — send a message.
id
string · path
to
array
cc
array
bcc
array
subject
string · max length: 998
body_text
string
body_html
string
is_draft
signature_id
string · min length: 1
attachments
array
in_reply_to
string · max length: 998
references
string · max length: 8000
propertyName
anything
/chats/example/messages
/notifications/:id
undocumented /notifications/:id
Hard-delete a single notification.
id
string · path
/notifications/example
/notifications
undocumented /notifications
/notifications
/notifications/unread-count
undocumented /notifications/unread-count
/notifications/unread-count
/notifications/:id
undocumented /notifications/:id
Mark a single notification as read.
id
string · path
/notifications/example
/notifications
undocumented /notifications
Mark all notifications as read for the authenticated member.
/notifications
/onboarding/handle-check
undocumented /onboarding/handle-check
GET /onboarding/handle-check?handle=xxx — Check if a workspace handle is available.
/onboarding/handle-check
/onboarding/payments
Capture onboarding payment
POST /accounts/onboarding/payment — Add card via Flutterwave v4.
card_number
string · min length: 13 · max length: 19
expiry_month
string · min length: 1 · max length: 2
expiry_year
string · min length: 2 · max length: 4
cvv
string · min length: 3 · max length: 4
propertyName
anything
/onboarding/payments
/onboarding/steps
undocumented /onboarding/steps
POST /accounts/onboarding/skip-payment — Skip payment step.
/onboarding/steps
/onboarding/invitations
Send onboarding invites
POST /accounts/onboarding/invites — Invite collaborators.
emails
array
propertyName
anything
/onboarding/invitations
/onboarding/completions
undocumented /onboarding/completions
POST /accounts/onboarding/complete — Mark workspace as onboarded.
/onboarding/completions
/onboarding/profile
Setup onboarding profile
PUT /accounts/onboarding/profile — Update avatar and workspace theme.
avatar_url
string · max length: 2048
propertyName
anything
/onboarding/profile
/onboarding/handle
Set workspace handle
PUT /onboarding/handle — Set the workspace handle and display name.
handle
string · min length: 3 · max length: 30
name
string · min length: 1 · max length: 200
propertyName
anything
/onboarding/handle
/online
undocumented /online
List workspace members who are currently online.
/online
/finance/orders/:entry_id
Transition an order
entry_id
string · path
status
propertyName
anything
/finance/orders/example
/finance/orders
Create an order
date
string · min length: 10
items
array
contact_mrn
string
company_mrn
string
currency
exchange_rate
number
memo
string · max length: 5000
tags
array
sources
array
adjustments
array
idempotency_key
string · max length: 100
propertyName
anything
/finance/orders
/finance/orders/:entry_id/fulfillments
Record a fulfillment
Record a fulfillment — auto-creates a draft invoice with selected lines.
entry_id
string · path
date
string · min length: 10
lines
array
memo
string · max length: 2000
propertyName
anything
/finance/orders/example/fulfillments
/finance/orders/:entry_id
Update a draft order
entry_id
string · path
status
fulfillment
object
propertyName
anything
/finance/orders/example
/organisations/:org_id
Update organisation
PUT /accounts/organisation — Update org details.
org_id
string · path
name
string · min length: 1 · max length: 200
email_domain
string
industry
string
size
string
timezone
string · max length: 64
propertyName
anything
/organisations/example
/ptos
Request time off
policy_id
string · min length: 1
start_date
string · min length: 1
end_date
string · min length: 1
half_day
reason
string · max length: 1000
propertyName
anything
/ptos
/ptos/:id
Update a pending PTO
id
string · path
start_date
string · min length: 1
end_date
string · min length: 1
half_day
reason
string · max length: 1000
propertyName
anything
/ptos/example
/ptos/:id/decision
Approve or deny a PTO
Approve or deny a PTO (manager/admin).
id
string · path
decision
note
string · max length: 1000
propertyName
anything
/ptos/example/decision
/papers/trash
undocumented /papers/trash
DELETE /papers/trash — destroy every trashed document the caller manages. Scoped by the same query as the listing, so this can only ever destroy what the caller was already being shown. It never touches a colleague's trash.
/papers/trash
/papers/trash/:document_id
undocumented /papers/trash/:document_id
DELETE /papers/trash/:document_id — destroy a trashed document for good. The purge gate has already confirmed the document is in the trash and that the caller manages it (CLAUDE.md rule 18). Versions, comments and collaborator rows go with it through ON DELETE CASCADE; the grants are not foreign keys, so they are revoked explicitly.
document_id
string · path
/papers/trash/example
/papers/:document_id
undocumented /papers/:document_id
DELETE /papers/:document_id — move a document to the trash. The delete gate has already loaded the document onto ctx.authz.document (CLAUDE.md rule 18). Grants are deliberately LEFT INTACT here. This used to call revoke_all, on the reasoning that the document was gone, which quietly made the trash unimplementable: a restored document came back with no grants at all, not even its owner's, so nobody could open, edit or delete it ever again. Grants are dropped at permanent deletion instead, in api_purge_document.
document_id
string · path
/papers/example
/papers/:document_id/comments/:comment_id
undocumented /papers/:document_id/comments/:comment_id
DELETE /papers/:document_id/comments/:comment_id — delete a comment. The delete gate (authz.can_delete_comment) has already loaded the comment onto ctx.authz.comment and confirmed the caller authored it or manages the document, so there's no re-query here (CLAUDE.md rule 18).
document_id
string · path
comment_id
string · path
/papers/example/comments/example
/papers
undocumented /papers
GET /papers — list documents for the workspace.
/papers
/papers/web-images
undocumented /papers/web-images
GET /papers/web-images?q=&page= — search openly-licensed web images.
/papers/web-images
/papers/trash
undocumented /papers/trash
GET /papers/trash — documents in the trash that the caller can restore.
/papers/trash
/papers/:document_id
undocumented /papers/:document_id
GET /papers/:document_id — get a single document with content.
document_id
string · path
/papers/example
/papers/:document_id/exports/:format
undocumented /papers/:document_id/exports/:format
GET /papers/:document_id/exports/:format — download as docx, odt, or pdf. The read gate (authz.can_view_doc) has already loaded the document onto ctx.authz.document, so there's no re-query here (CLAUDE.md rule 18).
document_id
string · path
format
string · path
/papers/example/exports/example
/papers/:document_id/versions
undocumented /papers/:document_id/versions
GET /papers/:document_id/versions — list version history.
document_id
string · path
/papers/example/versions
/papers/:document_id/versions/:version_id
undocumented /papers/:document_id/versions/:version_id
GET /papers/:document_id/versions/:version_id — get a single version.
document_id
string · path
version_id
string · path
/papers/example/versions/example
/papers/:document_id/comments
undocumented /papers/:document_id/comments
GET /papers/:document_id/comments — list comments for a document.
document_id
string · path
/papers/example/comments
/papers/:document_id/presence
undocumented /papers/:document_id/presence
GET /papers/:document_id/presence — get active collaborators.
document_id
string · path
/papers/example/presence
/papers/:document_id
Update a document
PATCH /papers/:document_id — update a document, or restore it from trash. The update gate (authz.can_update_doc) has already loaded the document onto ctx.authz.document and decided what this caller may do with it, including the trashed case, so there's no re-query here (CLAUDE.md rule 18).
document_id
string · path
title
string · min length: 1 · max length: 500
icon
string · max length: 100
icon_type
content
string
is_starred
page_mode
visibility
page_setup
object
deleted
propertyName
anything
/papers/example
/papers/:document_id/versions/:version_id
Name or rename a version
PATCH /papers/:document_id/versions/:version_id — name or rename a version.
document_id
string · path
version_id
string · path
name
string · max length: 120
propertyName
anything
/papers/example/versions/example
/papers/:document_id/comments/:comment_id
Resolve/unresolve comment
PATCH /papers/:document_id/comments/:comment_id — resolve or unresolve.
document_id
string · path
comment_id
string · path
resolved
propertyName
anything
/papers/example/comments/example
/papers
Create a document
POST /papers — create a new document.
title
string · min length: 1 · max length: 500
icon
string · max length: 100
icon_type
content
string
propertyName
anything
/papers
/papers/imports
undocumented /papers/imports
POST /papers/imports — create a new document from an uploaded .docx/.odt.
/papers/imports
/papers/:document_id/images
undocumented /papers/:document_id/images
POST /papers/:document_id/images: keep an uploaded image with this document, privately.
document_id
string · path
/papers/example/images
/papers/:document_id/image-imports
Bring a web image into a document
POST /papers/:document_id/image-imports: bring an image into this document, privately. A web URL is fetched; another document's picture is copied, so this document never depends on that one.
document_id
string · path
url
string · min length: 1 · max length: 2000
propertyName
anything
/papers/example/image-imports
/papers/:document_id/versions
Snapshot a named version
POST /papers/:document_id/versions — snapshot the current state as a named version. The edit gate (authz.can_edit_doc) has already loaded the document onto ctx.authz.document, so there's no re-query here (CLAUDE.md rule 18).
document_id
string · path
name
string · min length: 1 · max length: 120
propertyName
anything
/papers/example/versions
/papers/:document_id/comments
Add a comment
POST /papers/:document_id/comments — add a comment.
document_id
string · path
body
string · min length: 1 · max length: 4000
object_id
string · max length: 64
parent_id
string · max length: 64
nx
number
ny
number
propertyName
anything
/papers/example/comments
/papers/:document_id/presence
undocumented /papers/:document_id/presence
PUT /papers/:document_id/presence — update cursor position.
document_id
string · path
/papers/example/presence
/calls/:id/participants/:member_mrn
Update participant role
id
string · path
member_mrn
string · path
role
status
can_speak
propertyName
anything
/calls/example/participants/example
/chats/:id/participants/:member_mrn
Update participant role
PATCH /chats/:id/participants/:member_mrn — change a participant's role.
id
string · path
member_mrn
string · path
role
status
can_speak
propertyName
anything
/chats/example/participants/example
/calls/:id/participants
Invite participants
id
string · path
members
array
propertyName
anything
/calls/example/participants
/chats/:id/participants
Add participants
POST /chats/:id/participants — add participants to a group.
id
string · path
members
array
history
history_days
integer · min: 1 · max: 3650
share_history
propertyName
anything
/chats/example/participants
/payment-methods/:pm_id
undocumented /payment-methods/:pm_id
DELETE /payment-methods/:pm_id — Remove a payment method.
pm_id
string · path
/payment-methods/example
/payment-methods/:pm_id
undocumented /payment-methods/:pm_id
PUT /payment-methods/:pm_id — Set default payment method.
pm_id
string · path
/payment-methods/example
/finance/payments/:payment_id
Apply allocations
Apply new allocations to an unallocated (or partially-allocated) payment.
payment_id
string · path
allocations
array
propertyName
anything
/finance/payments/example
/finance/payments
Record a payment
direction
amount
number
method
paid_at
string · min length: 10
bank_account_id
string
allocations
array
allocate_entry_id
string
allocate_entry_amount
number
allow_overpayment
contact_mrn
string
company_mrn
string
currency
exchange_rate
number
reference
string · max length: 200
memo
string · max length: 2000
idempotency_key
string · max length: 100
propertyName
anything
/finance/payments
/finance/payments/:payment_id/reversals
Reverse a payment
payment_id
string · path
reason
string · min length: 1 · max length: 500
propertyName
anything
/finance/payments/example/reversals
/finance/fiscal-periods/:period_id
Update/close a period
period_id
string · path
name
string · min length: 1 · max length: 50
start
string · min length: 10
end
string · min length: 10
status
propertyName
anything
/finance/fiscal-periods/example
/finance/fiscal-periods
Create a fiscal period
name
string · min length: 1 · max length: 50
start
string · min length: 10
end
string · min length: 10
status
propertyName
anything
/finance/fiscal-periods
/finance/fiscal-periods/:period_id/revaluations
Run period-end FX revaluation
POST /finance/fiscal-periods/:period_id/revaluations Runs one revaluation for the period at the given ``as_of``, applying the supplied closing rates to every open foreign-currency monetary position. Posts a journal entry (``type=journal``, ``status=posted``) and schedules the reversing entry for the first day of the next period.
period_id
string · path
as_of
string · min length: 10
rates
propertyName
anything
/finance/fiscal-periods/example/revaluations
/folders/:folder_id/permissions
Update folder permission
folder_id
string · path
member_mrn
string · min length: 1
role
propertyName
anything
/folders/example/permissions
/files/:file_id/permissions
Update file permission
file_id
string · path
member_mrn
string · min length: 1
role
propertyName
anything
/files/example/permissions
/folders/:folder_id/permissions
Grant folder permissions
folder_id
string · path
members
array
propertyName
anything
/folders/example/permissions
/files/:file_id/permissions
Grant file permissions
file_id
string · path
members
array
propertyName
anything
/files/example/permissions
/pipelines/:pipeline_id
undocumented /pipelines/:pipeline_id
pipeline_id
string · path
/pipelines/example
/pipelines/:pipeline_id/stages/:stage_id
undocumented /pipelines/:pipeline_id/stages/:stage_id
pipeline_id
string · path
stage_id
string · path
/pipelines/example/stages/example
/pipelines
undocumented /pipelines
/pipelines
/pipelines/:pipeline_id
undocumented /pipelines/:pipeline_id
pipeline_id
string · path
/pipelines/example
/pipelines/:pipeline_id/stages
undocumented /pipelines/:pipeline_id/stages
pipeline_id
string · path
/pipelines/example/stages
/pipelines
Create a pipeline
name
string · min length: 1 · max length: 100
description
string · max length: 1000
is_default
propertyName
anything
/pipelines
/pipelines/:pipeline_id/stages
Add a stage to a pipeline
pipeline_id
string · path
name
string · min length: 1 · max length: 100
type
key
string · max length: 50
position
integer · min: 0 · max: 999
criteria
array
questions
array
default_interviewers
array
required_evaluations
integer · min: 0 · max: 20
sla_days
integer · min: 0 · max: 365
duration_minutes
integer · min: 0 · max: 600
propertyName
anything
/pipelines/example/stages
/pipelines/:pipeline_id
Update a pipeline
pipeline_id
string · path
name
string · min length: 1 · max length: 100
description
string · max length: 1000
is_default
status
propertyName
anything
/pipelines/example
/pipelines/:pipeline_id/stages/:stage_id
Update a stage
pipeline_id
string · path
stage_id
string · path
name
string · min length: 1 · max length: 100
type
key
string · max length: 50
criteria
array
questions
array
default_interviewers
array
required_evaluations
integer · min: 0 · max: 20
sla_days
integer · min: 0 · max: 365
duration_minutes
integer · min: 0 · max: 600
propertyName
anything
/pipelines/example/stages/example
/plan
undocumented /plan
GET /plan: current plan, price book, currency and billing interval.
/plan
/finance/quotes/:entry_id/links
Share a quote with a customer
entry_id
string · path
recipient_email
string · max length: 320
propertyName
anything
/finance/quotes/example/links
/finance/invoices/:entry_id/links
Share an invoice with a customer
entry_id
string · path
recipient_email
string · max length: 320
propertyName
anything
/finance/invoices/example/links
/finance/credit-notes/:entry_id/links
Share a credit note with a customer
entry_id
string · path
recipient_email
string · max length: 320
propertyName
anything
/finance/credit-notes/example/links
/finance/payment-credentials/:provider
Store workspace payment keys
Store a workspace's own provider keys, encrypted at rest. The raw key is write-only: responses only ever carry the mask.
provider
string · path
secret_key
string · min length: 8 · max length: 200
public_key
string · max length: 200
enabled
propertyName
anything
/finance/payment-credentials/example
/preferences
undocumented /preferences
/preferences
/preferences
undocumented /preferences
/preferences
/presignations/:id
undocumented /presignations/:id
DELETE /presignations/:id — abandon a multipart upload so no orphaned parts linger (R2 bills incomplete parts until aborted).
id
string · path
/presignations/example
/presignations
undocumented /presignations
POST /presignations — generate a presigned R2 PUT URL. Body: {app, filename, content_type, size_bytes, context: {...}}
/presignations
/presignations/:id/confirmations
undocumented /presignations/:id/confirmations
POST /presignations/:id/confirmations — confirm upload completed. Emits ``system.{app}.upload.confirmed`` with the upload metadata + app context so the originating app can do its bookkeeping. The client-supplied fields are treated as claims, not facts: the storage key must live inside the caller's own workspace namespace, and when R2 is configured the object is HEAD-verified so the size the apps record (and quota checks trust) is what R2 actually holds, not what the client typed.
id
string · path
/presignations/example/confirmations
/presignations/:id/completions
undocumented /presignations/:id/completions
POST /presignations/:id/completions — stitch uploaded parts together. Body: {app, storage_key, r2_upload_id, parts: [{part_number, etag}]}. The client still calls the confirmation endpoint afterwards; that is where the HEAD verification and app bookkeeping happen.
id
string · path
/presignations/example/completions
/me/locale
Set your UI language
PUT /me/locale — save the UI language this person picked. Written to profiles, not members: the preference belongs to the individual, so it follows them into every workspace they belong to and onto every device they sign in from. A workspace never overrides it. Three places are updated together, and all three matter: * profiles.locale — the durable record, read at sign-in on a new device * the session blob — what the locale middleware reads per request * the cookie — so signing out does not drop the login page back to English, and so the marketing site agrees with the app The caller reloads afterwards. Every surface is server-rendered, so there is nothing to re-translate in place.
locale
propertyName
anything
/me/locale
/profiles/:member_id
Update profile
Update own profile (name, job title).
member_id
string · path
full_name
string · min length: 1 · max length: 200
job_title
string · max length: 200
propertyName
anything
/profiles/example
/profiles/:member_id/contact
Update contact info
PUT /profiles/:member_id/contact — update phone number and address. Writes the CURRENT WORKSPACE's copy, not the shared profile. Before migration 080 these six fields lived only on profiles, so two workspaces inviting the same email shared one row: handing your mobile to one employer published it to every other workspace you belonged to. Same reason migration 035 moved name, title and avatar.
member_id
string · path
phone_number
string · max length: 50
street
string · max length: 300
city
string · max length: 100
state
string · max length: 100
postal_code
string · max length: 20
country
string · max length: 100
propertyName
anything
/profiles/example/contact
/passwords/:member_id
Set or change password
Set or change your own password. This is also the only way to SET one, because there is no forgot-password flow: if you cannot remember it, you sign in with a mailed link and come here. So the current password is required only when one exists. Somebody who joined by link and has never had a password proves nothing beyond the live session they are already holding, and demanding a password they do not have would strand them with no way to ever get one.
member_id
string · path
new_password
string · min length: 8
current_password
string · min length: 1
propertyName
anything
/passwords/example
/workers/:worker_id/fields
Update a worker's custom field values
PATCH custom field values: {values: [{field_id, value}]}. A null/empty value clears the field. Values are validated against the definition type.
worker_id
string · path
values
array
propertyName
anything
/workers/example/fields
/workers/fields
Create a custom profile field
label
string · min length: 1 · max length: 100
type
section
string · max length: 100
options
array
required
sensitive
help_text
string · max length: 300
position
integer · min: 0 · max: 10000
propertyName
anything
/workers/fields
/workers/fields/:field_id
Update a custom profile field
field_id
string · path
label
string · min length: 1 · max length: 100
section
string · max length: 100
options
array
required
sensitive
help_text
string · max length: 300
position
integer · min: 0 · max: 10000
propertyName
anything
/workers/fields/example
/ptos/:id
undocumented /ptos/:id
Cancel a PTO (worker) or revoke (manager).
id
string · path
/ptos/example
/ptos
undocumented /ptos
/ptos
/ptos/pending
undocumented /ptos/pending
List pending PTOs the current user can approve. A user approves their direct reports (workers whose manager is them). The projection stores ``manager_id`` as a *worker* id, so we resolve the viewer's own worker id and match against it — never against the member id. Owners and admins additionally approve workers who have no manager at all (the no-manager fallback). A user never approves their own request.
/ptos/pending
/ptos/:id
undocumented /ptos/:id
id
string · path
/ptos/example
/finance/purchase-credit-notes/:entry_id
Issue/void purchase credit note
entry_id
string · path
status
propertyName
anything
/finance/purchase-credit-notes/example
/finance/purchase-credit-notes
Record a vendor credit note
date
string · min length: 10
items
array
source_entry_id
string · min length: 1
contact_mrn
string
company_mrn
string
currency
exchange_rate
number
memo
string · max length: 5000
adjustments
array
dimensions
idempotency_key
string · max length: 100
propertyName
anything
/finance/purchase-credit-notes
/finance/purchase-credit-notes/:entry_id/allocations
Set vendor credit against a bill
entry_id
string · path
entry_id
string · min length: 1
amount
number
entry_amount
number
propertyName
anything
/finance/purchase-credit-notes/example/allocations
/finance/purchase-credit-notes/:entry_id
Update a draft purchase credit note
entry_id
string · path
date
string · min length: 10
items
array
contact_mrn
string
company_mrn
string
currency
exchange_rate
number
memo
string · max length: 5000
adjustments
array
dimensions
propertyName
anything
/finance/purchase-credit-notes/example
/finance/purchase-orders/:entry_id
Transition a PO
entry_id
string · path
status
propertyName
anything
/finance/purchase-orders/example
/finance/purchase-orders
Create a purchase order
date
string · min length: 10
items
array
company_mrn
string
contact_mrn
string
currency
exchange_rate
number
memo
string · max length: 5000
tags
array
adjustments
array
idempotency_key
string · max length: 100
propertyName
anything
/finance/purchase-orders
/finance/purchase-orders/:entry_id/receipts
Record a receipt
Record a receipt against a PO — auto-creates a draft bill with the selected lines.
entry_id
string · path
date
string · min length: 10
lines
array
memo
string · max length: 2000
propertyName
anything
/finance/purchase-orders/example/receipts
/finance/purchase-orders/:entry_id
Update a draft PO
entry_id
string · path
date
string · min length: 10
items
array
company_mrn
string
contact_mrn
string
currency
exchange_rate
number
memo
string · max length: 5000
tags
array
adjustments
array
dimensions
propertyName
anything
/finance/purchase-orders/example
/push-devices/:id
undocumented /push-devices/:id
DELETE /push-devices/:id: stop notifying this phone.
id
string · path
/push-devices/example
/push-subscriptions/:id
undocumented /push-subscriptions/:id
DELETE /push-subscriptions/:id: stop notifying this browser.
id
string · path
/push-subscriptions/example
/finance/quotes/:entry_id
Transition a quote
entry_id
string · path
status
propertyName
anything
/finance/quotes/example
/finance/quotes
Create a quote
date
string · min length: 10
items
array
contact_mrn
string
company_mrn
string
currency
exchange_rate
number
valid_until
string · min length: 10
memo
string · max length: 5000
tags
array
adjustments
array
idempotency_key
string · max length: 100
propertyName
anything
/finance/quotes
/finance/quotes/:entry_id/sends
Email a quote
entry_id
string · path
to
string · min length: 1 · max length: 500
cc
string · max length: 500
subject
string · max length: 300
message
string · max length: 5000
propertyName
anything
/finance/quotes/example/sends
/finance/quotes/:entry_id/revisions
Revise a sent quote
Revise a sent/rejected quote: supersede the original and create a new draft revision carrying the edits. With ``resend`` (and a known recipient) the revision is emailed and marked sent in one step.
entry_id
string · path
date
string · min length: 10
items
array
contact_mrn
string
company_mrn
string
currency
exchange_rate
number
valid_until
string · min length: 10
memo
string · max length: 5000
tags
array
resend
to
string · max length: 500
propertyName
anything
/finance/quotes/example/revisions
/finance/quotes/:entry_id
Update a draft quote
entry_id
string · path
date
string · min length: 10
items
array
contact_mrn
string
company_mrn
string
currency
exchange_rate
number
valid_until
string · min length: 10
memo
string · max length: 5000
tags
array
adjustments
array
dimensions
propertyName
anything
/finance/quotes/example
/chats/:id/messages/:msg_id/reactions
Add a reaction
POST /chats/:id/messages/:msg_id/reactions — add an emoji reaction.
id
string · path
msg_id
string · path
emoji
string · min length: 1 · max length: 32
propertyName
anything
/chats/example/messages/example/reactions
/sign/envelopes/:envelope_id/recipients/:recipient_id
Edit a recipient
PATCH /sign/envelopes/:envelope_id/recipients/:recipient_id — edit a recipient (before send).
envelope_id
string · path
recipient_id
string · path
name
string · min length: 1 · max length: 200
email
string · email
role
string · min length: 1 · max length: 100
recipient_type
signer_mrn
string
signing_order
integer
access_code
string · min length: 4 · max length: 64
propertyName
anything
/sign/envelopes/example/recipients/example
/sign/envelopes/:envelope_id/recipients
Add a recipient
POST /sign/envelopes/:envelope_id/recipients — add a recipient (member or external guest).
envelope_id
string · path
name
string · min length: 1 · max length: 200
email
string · email
role
string · min length: 1 · max length: 100
recipient_type
signer_mrn
string
signing_order
integer
access_code
string · min length: 4 · max length: 64
propertyName
anything
/sign/envelopes/example/recipients
/finance/bank-rules/:rule_id
Update a bank rule
rule_id
string · path
name
string · min length: 1 · max length: 100
match
object
action
object
propertyName
anything
/finance/bank-rules/example
/finance/bank-imports
Import a bank feed
bank_account_id
string · min length: 1
rows
array
propertyName
anything
/finance/bank-imports
/finance/bank-imports/:import_id/entries
Create an entry from a bank import
Create a bill/invoice for an unmatched bank import and reconcile the import against it in one step. The category comes from the request body or from the first matching bank rule.
import_id
string · path
account_code
string · max length: 20
description
string · max length: 500
entry_type
propertyName
anything
/finance/bank-imports/example/entries
/finance/bank-connections
Connect a bank account
code
string · min length: 1 · max length: 200
propertyName
anything
/finance/bank-connections
/finance/reconciliations
Finalise a reconciliation
bank_account_id
string · min length: 1
period_start
string · min length: 10
period_end
string · min length: 10
statement_balance
number
propertyName
anything
/finance/reconciliations
/finance/bank-rules
Create a bank rule
name
string · min length: 1 · max length: 100
match
object
action
object
propertyName
anything
/finance/bank-rules
/calls/:id/recordings/:recording_id
Abort a recording
Abandon a recording: abort the R2 multipart upload and mark it failed. Host-only.
id
string · path
recording_id
string · path
status
upload_id
string · min length: 1 · max length: 512
propertyName
anything
/calls/example/recordings/example
/calls/:id/recordings
Start a recording
id
string · path
content_type
string · max length: 100
propertyName
anything
/calls/example/recordings
/calls/:id/recordings/:recording_id
Complete a recording
Finalize a recording: assemble the uploaded parts in R2 and mark it ready. Host-only.
id
string · path
recording_id
string · path
upload_id
string · min length: 1 · max length: 512
parts
array
size_bytes
integer · min: 0
duration_seconds
integer · min: 0
propertyName
anything
/calls/example/recordings/example
/recovery-codes
undocumented /recovery-codes
/recovery-codes
/recovery-codes
undocumented /recovery-codes
/recovery-codes
/finance/recurring-entries/:recurring_id
Update recurring entry
recurring_id
string · path
name
string · min length: 1 · max length: 200
type
frequency
next_date
string · min length: 10
company_mrn
string
contact_mrn
string
items
array
auto_approve
propertyName
anything
/finance/recurring-entries/example
/finance/recurring-entries
Create recurring entry
name
string · min length: 1 · max length: 200
type
frequency
next_date
string · min length: 10
company_mrn
string
contact_mrn
string
items
array
auto_approve
propertyName
anything
/finance/recurring-entries
/reports/burndown
undocumented /reports/burndown
Return burndown + burnup chart data for a schedule (or board-wide).
/reports/burndown
/finance/requests/:request_id
Approve or decline a request
PATCH /finance/requests/:id — approve (books the artifact) or decline.
request_id
string · path
status
reason
string · max length: 1000
propertyName
anything
/finance/requests/example
/finance/requests
File an expense claim, advance, or purchase request
POST /finance/requests — any portal member files their own request.
kind
amount
number
date
string · min length: 10
description
string · min length: 1 · max length: 2000
currency
category_code
string · max length: 20
vendor
string · max length: 200
needed_by
string · min length: 10
receipts
array
dimensions
propertyName
anything
/finance/requests
/finance/requests/:request_id/payments
Pay out an approved request
POST /finance/requests/:id/payments — pay out an approved request. Expenses settle the bill the approval created (outbound payment, AP → cash). Advances post a journal (Employee Advances ← cash). Purchases are paid through their PO chain, never directly.
request_id
string · path
bank_account_id
string
propertyName
anything
/finance/requests/example/payments
/finance/requests/:request_id/messages
Message on a request thread
POST /finance/requests/:id/messages — the claimant or a reviewer leaves a message on the request's thread. Visibility follows the request itself (scope deposited by the authz chain).
request_id
string · path
body
string · min length: 1 · max length: 2000
propertyName
anything
/finance/requests/example/messages
/requests/:update_id
undocumented /requests/:update_id
PUT /requests/:update_id — Approve or deny an install request via status field.
update_id
string · path
/requests/example
/roles/:role_id
undocumented /roles/:role_id
DELETE /accounts/organisation/roles/:role_id — Delete a role.
role_id
string · path
/roles/example
/roles/:role_id/members/:member_id
undocumented /roles/:role_id/members/:member_id
DELETE /accounts/organisation/roles/:role_id/members/:member_id — Remove member from role.
role_id
string · path
member_id
string · path
/roles/example/members/example
/roles
undocumented /roles
GET /roles — List custom roles for the workspace (admin view).
/roles
/roles
Create role
POST /accounts/organisation/roles — Create a role.
name
string · min length: 1 · max length: 100
description
string · max length: 500
propertyName
anything
/roles
/roles/:role_id/members
Assign member to role
POST /accounts/organisation/roles/:role_id/members — Assign member to role.
role_id
string · path
member_id
string · min length: 1
propertyName
anything
/roles/example/members
/roles/:role_id
undocumented /roles/:role_id
PUT /accounts/organisation/roles/:role_id — Update role + permissions.
role_id
string · path
/roles/example
/roles/:role_id/default
Set role as default
Toggle whether a role is auto-assigned to new members. Body: {is_default: bool}
role_id
string · path
is_default
propertyName
anything
/roles/example/default
/rooms/:id
undocumented /rooms/:id
Permanently delete a room. Kicks all connected participants, then removes the room row (live_room_members rows cascade via FK).
id
string · path
/rooms/example
/rooms/:id/members/:member_mrn
undocumented /rooms/:id/members/:member_mrn
Remove member from room.
id
string · path
member_mrn
string · path
/rooms/example/members/example
/rooms/:id/sessions
undocumented /rooms/:id/sessions
Leave a room. Sets is_connected = FALSE.
id
string · path
/rooms/example/sessions
/rooms
undocumented /rooms
List rooms visible to the current member. Supports ?q= search and pagination.
/rooms
/rooms/:id
undocumented /rooms/:id
Get room details + full member list with connection status.
id
string · path
/rooms/example
/rooms/:id/members
undocumented /rooms/:id/members
List room members with connection/mute state.
id
string · path
/rooms/example/members
/rooms/:id
Update a room
Update room name, description, settings, type.
id
string · path
name
string · min length: 1 · max length: 50
description
string · max length: 200
type
max_participants
integer · min: 2 · max: 100
settings
object
propertyName
anything
/rooms/example
/rooms/:id/members/:member_mrn
Update room member role
Update member role (promote/demote admin).
id
string · path
member_mrn
string · path
role
propertyName
anything
/rooms/example/members/example
/rooms
Create a room
Create a new room. Creator becomes room admin.
name
string · min length: 1 · max length: 50
description
string · max length: 200
type
max_participants
integer · min: 2 · max: 100
settings
object
propertyName
anything
/rooms
/rooms/:id/members
Add room members
Add member(s) to a room.
id
string · path
members
array
propertyName
anything
/rooms/example/members
/rooms/:id/sessions
undocumented /rooms/:id/sessions
Join a room. Generates a LiveKit access token. Sets is_connected = TRUE.
id
string · path
/rooms/example/sessions
/rooms/:id/token
undocumented /rooms/:id/token
Mint a fresh LiveKit token for a room the member is already connected to. Unlike POST /rooms/:id/sessions (which runs the full join lifecycle — kicks stale participants, updates is_connected, emits events), this endpoint is a pure token refresh. Used by the client's proactive refresh timer before the current token's `exp` claim kicks in.
id
string · path
/rooms/example/token
/rooms/:id/members/:member_mrn/mute
undocumented /rooms/:id/members/:member_mrn/mute
Mute a participant (room admin only). Signals via platform WS.
id
string · path
member_mrn
string · path
/rooms/example/members/example/mute
/rooms/session-state
undocumented /rooms/session-state
PUT /rooms/session-state — Sync client-side mute state into session for restore on refresh.
/rooms/session-state
/schedules/:schedule_id
undocumented /schedules/:schedule_id
Delete a schedule. Its tasks and deliverables are kept — the schedule link is cleared via the ON DELETE SET NULL foreign key, so they fall back to having no schedule rather than being deleted.
schedule_id
string · path
/schedules/example
/schedules
undocumented /schedules
GET /schedules?board_id=...&q=... — list schedules for a board, optionally filtered by name.
/schedules
/schedules
Create a schedule
board_id
string
name
string · min length: 1 · max length: 200
start_date
string · min length: 1
end_date
string · min length: 1
goal
string · max length: 500
description
string · max length: 5000
status
propertyName
anything
/schedules
/schedules/:schedule_id
Update a schedule
Update a schedule's mutable fields.
schedule_id
string · path
name
string · min length: 1 · max length: 200
goal
string · max length: 500
description
string · max length: 5000
status
start_date
string
end_date
string
propertyName
anything
/schedules/example
/scoring/rules/:rule_id
undocumented /scoring/rules/:rule_id
rule_id
string · path
/scoring/rules/example
/scoring/rules
undocumented /scoring/rules
/scoring/rules
/scoring/rules/:rule_id
undocumented /scoring/rules/:rule_id
rule_id
string · path
/scoring/rules/example
/scoring/:entity_type/:entity_id
undocumented /scoring/:entity_type/:entity_id
Compute a score on demand. Deal scores persist on the deal and threshold events fire only on crossings (comparing against the stored score). Contact scores are computed read-only here; the daily sweep in events.py owns persistence and threshold events for contacts, because apis.py must never write the crm_party_projection.
entity_type
string · path
entity_id
string · path
/scoring/example/example
/scoring/rules
Create a scoring rule
name
string · min length: 1 · max length: 200
entity_type
rules
array
thresholds
array
enabled
propertyName
anything
/scoring/rules
/scoring/rules/:rule_id
Update a scoring rule
rule_id
string · path
name
string · min length: 1 · max length: 200
rules
array
thresholds
array
enabled
propertyName
anything
/scoring/rules/example
/search
undocumented /search
GET /search?app=tasks&q=PL-417&types=task: search one app, best match first.
/search
/search
Search one app
POST /search with {app, q, types, filters}: the same search with a structured body.
app
string · min length: 1 · max length: 64
q
string · max length: 2000
types
array
filters
object
propertyName
anything
/search
/segments/:segment_id
undocumented /segments/:segment_id
DELETE /segments/:segment_id — delete a segment.
segment_id
string · path
/segments/example
/segments/:segment_id/members/:member_id
undocumented /segments/:segment_id/members/:member_id
DELETE /segments/:segment_id/members/:member_id — remove from a static segment.
segment_id
string · path
member_id
string · path
/segments/example/members/example
/segments
undocumented /segments
GET /segments — list segments.
/segments
/segments/:segment_id
undocumented /segments/:segment_id
GET /segments/:segment_id — get segment with resolved members.
segment_id
string · path
/segments/example
/segments
Create a segment
POST /segments — create a segment (static or dynamic).
name
string · min length: 1 · max length: 100
description
string · max length: 500
type
entity_type
filter
object
members
array
propertyName
anything
/segments
/segments/:segment_id/members
Add member to segment
POST /segments/:segment_id/members — add a contact/company to a static segment.
segment_id
string · path
type
id
string · min length: 1
propertyName
anything
/segments/example/members
/segments/:segment_id
Update a segment
PUT /segments/:segment_id — update a segment (name, description, or rules).
segment_id
string · path
name
string · min length: 1 · max length: 100
description
string · max length: 500
filter
object
propertyName
anything
/segments/example
/chats/:id/settings
Update chat settings
PATCH /chats/:id/settings — per-chat settings for the caller (mute).
id
string · path
muted_until
string
propertyName
anything
/chats/example/settings
/finance/tax-rates/:tax_id
Update tax preset
tax_id
string · path
name
string · min length: 1 · max length: 100
rates
array
propertyName
anything
/finance/tax-rates/example
/finance/payment-terms/:term_id
Update payment term
term_id
string · path
name
string · min length: 1 · max length: 100
days
integer · min: 0
early_discount_rate
number
early_discount_days
integer
propertyName
anything
/finance/payment-terms/example
/finance/tax-rates
Create tax preset
name
string · min length: 1 · max length: 100
rates
array
propertyName
anything
/finance/tax-rates
/finance/payment-terms
Create payment term
name
string · min length: 1 · max length: 100
days
integer · min: 0
early_discount_rate
number
early_discount_days
integer
propertyName
anything
/finance/payment-terms
/finance/settings
Update core settings
base_currency
fiscal_year_start
integer · min: 1 · max: 12
accounting_enabled
number_prefixes
object
sequential_numbers
default_accounts
object
invoice_template
object
propertyName
anything
/finance/settings
/shared
undocumented /shared
/shared
/shares/:share_id
undocumented /shares/:share_id
share_id
string · path
/shares/example
/shares
undocumented /shares
/shares
/shares/:share_id
undocumented /shares/:share_id
share_id
string · path
/shares/example
/shares/:share_id
Update a share link
share_id
string · path
password
string · min length: 4 · max length: 128
expires_at
string
max_downloads
integer
is_active
propertyName
anything
/shares/example
/shares
Create a share link
slug
string · min length: 1 · max length: 200
propertyName
anything
/shares
/sign/envelopes/:envelope_id/documents/:document_id
undocumented /sign/envelopes/:envelope_id/documents/:document_id
DELETE /sign/envelopes/:envelope_id/documents/:document_id — remove one part. Fields sitting on the removed part's (global) pages are deleted; fields on later pages shift back by the removed page span so they stay on the pages they were placed on.
envelope_id
string · path
document_id
string · path
/sign/envelopes/example/documents/example
/sign/envelopes/:envelope_id
undocumented /sign/envelopes/:envelope_id
DELETE /sign/envelopes/:envelope_id — delete a draft/template (sent envelopes are voided, not deleted).
envelope_id
string · path
/sign/envelopes/example
/sign/templates/:envelope_id/links/:link_id
undocumented /sign/templates/:envelope_id/links/:link_id
DELETE /sign/templates/:envelope_id/links/:link_id — close a link. Soft (revoked_at): the row keeps its submission history.
envelope_id
string · path
link_id
string · path
/sign/templates/example/links/example
/sign/envelopes/:envelope_id/exports/:target
undocumented /sign/envelopes/:envelope_id/exports/:target
DELETE /sign/envelopes/:envelope_id/exports/:target — take the saved copy back out of Files. Files itself refuses to delete anything Sign owns, so this is the only way to undo a Save to Files. It has to live here: a completed envelope can never be deleted (sealed documents are voided, not removed), so without this the copy would be permanent and an accidental save unfixable.
envelope_id
string · path
target
string · path
/sign/envelopes/example/exports/example
/sign/envelopes/:envelope_id/fields/:field_id
undocumented /sign/envelopes/:envelope_id/fields/:field_id
DELETE /sign/envelopes/:envelope_id/fields/:field_id — remove a field.
envelope_id
string · path
field_id
string · path
/sign/envelopes/example/fields/example
/sign/envelopes/:envelope_id/recipients/:recipient_id
undocumented /sign/envelopes/:envelope_id/recipients/:recipient_id
DELETE /sign/envelopes/:envelope_id/recipients/:recipient_id — remove a recipient (before send).
envelope_id
string · path
recipient_id
string · path
/sign/envelopes/example/recipients/example
/sign/envelopes
undocumented /sign/envelopes
GET /sign/envelopes — list documents (non-templates by default; ?is_template=true, ?status=).
/sign/envelopes
/sign/envelopes/:envelope_id
undocumented /sign/envelopes/:envelope_id
GET /sign/envelopes/:envelope_id — envelope + its fields + recipients.
envelope_id
string · path
/sign/envelopes/example
/sign/envelopes/:envelope_id/source
undocumented /sign/envelopes/:envelope_id/source
GET /sign/envelopes/:envelope_id/source — presigned GET URLs for the source PDFs. The builder loads these into PDF.js to render pages for field placement. `documents` lists every part in signing order (a legacy single-PDF envelope synthesizes one entry); `url`/`page_count` keep the pre-multi-document shape (first part / total pages).
envelope_id
string · path
/sign/envelopes/example/source
/sign/envelopes/:envelope_id/documents
undocumented /sign/envelopes/:envelope_id/documents
GET /sign/envelopes/:envelope_id/documents — the envelope's source PDFs in order.
envelope_id
string · path
/sign/envelopes/example/documents
/sign/envelopes/:envelope_id/audit
undocumented /sign/envelopes/:envelope_id/audit
GET /sign/envelopes/:envelope_id/audit — the envelope's chronological audit trail.
envelope_id
string · path
/sign/envelopes/example/audit
/sign/envelopes/:envelope_id/audit/integrity
undocumented /sign/envelopes/:envelope_id/audit/integrity
GET /sign/envelopes/:envelope_id/audit/integrity: recompute the audit chain and report whether any row was altered, removed or forked.
envelope_id
string · path
/sign/envelopes/example/audit/integrity
/sign/envelopes/:envelope_id/values
undocumented /sign/envelopes/:envelope_id/values
GET /sign/envelopes/:envelope_id/values — what each recipient actually entered. Text/date/name/email come back as `value`; signature/initials come back as a short- lived presigned `signature_url` for the drawn PNG. The builder overlays these on a sent/completed document so the owner sees the real content, not the placeholders.
envelope_id
string · path
/sign/envelopes/example/values
/sign/envelopes/:envelope_id/document
undocumented /sign/envelopes/:envelope_id/document
GET /sign/envelopes/:envelope_id/document — presigned URL for the sealed PDF.
envelope_id
string · path
/sign/envelopes/example/document
/sign/envelopes/:envelope_id/certificate
undocumented /sign/envelopes/:envelope_id/certificate
GET /sign/envelopes/:envelope_id/certificate — presigned URL for the Certificate of Completion.
envelope_id
string · path
/sign/envelopes/example/certificate
/sign/templates
undocumented /sign/templates
GET /sign/templates — list reusable templates (sugar for ?is_template=true).
/sign/templates
/sign/templates/:envelope_id/usages
undocumented /sign/templates/:envelope_id/usages
GET /sign/templates/:envelope_id/usages: every document created from this template (one-off clones and broadcast sends), newest first, with sender and recipients attached. Visible to anyone holding a read grant on the template.
envelope_id
string · path
/sign/templates/example/usages
/sign/templates/:envelope_id/links
undocumented /sign/templates/:envelope_id/links
GET /sign/templates/:envelope_id/links — this template's self-serve links.
envelope_id
string · path
/sign/templates/example/links
/sign/signatories
undocumented /sign/signatories
GET /sign/signatories?q= : everyone ever added to a document the caller can see, aggregated by email: document count, signed/declined counts, and last activity.
/sign/signatories
/sign/signatories/:email
undocumented /sign/signatories/:email
GET /sign/signatories/:email — one signatory's profile (see _signatory_profile).
email
string · path
/sign/signatories/example
/sign/statistics
undocumented /sign/statistics
GET /sign/statistics: dashboard aggregates over the documents the caller can see (same visibility as the lists: grants, widened for auditors): status counts, monthly sent/completed volume, completion rate, median time-to-complete, pending-signature aging, top templates by usage, and recent activity.
/sign/statistics
/sign/jurisdictions
undocumented /sign/jurisdictions
GET /sign/jurisdictions — picker options + carve-out warnings (static config).
/sign/jurisdictions
/sign/settings
undocumented /sign/settings
GET /sign/settings: Sign's workspace configuration. Today that is one choice: which template a cross-app signature request is raised from. Readable by anyone who can see documents, so the Templates list can mark the chosen one even for members who may not change it.
/sign/settings
/sign/envelopes/:envelope_id/fields
undocumented /sign/envelopes/:envelope_id/fields
GET /sign/envelopes/:envelope_id/fields — list field placements.
envelope_id
string · path
/sign/envelopes/example/fields
/sign/envelopes/:envelope_id/recipients
undocumented /sign/envelopes/:envelope_id/recipients
GET /sign/envelopes/:envelope_id/recipients — list recipients + their status.
envelope_id
string · path
/sign/envelopes/example/recipients
/sign/envelopes/:envelope_id/recipients/:recipient_id/link
undocumented /sign/envelopes/:envelope_id/recipients/:recipient_id/link
GET /sign/envelopes/:envelope_id/recipients/:recipient_id/link: a recipient's signing link for a manager to pass on. Taking it is written to the audit trail.
envelope_id
string · path
recipient_id
string · path
/sign/envelopes/example/recipients/example/link
/sign/envelopes/:envelope_id/reminders
undocumented /sign/envelopes/:envelope_id/reminders
POST /sign/envelopes/:envelope_id/reminders — remind recipients who haven't signed.
envelope_id
string · path
/sign/envelopes/example/reminders
/sign/templates/:envelope_id/broadcasts
undocumented /sign/templates/:envelope_id/broadcasts
POST /sign/templates/:envelope_id/broadcasts {rows:[{recipients:[{role,name,email}]}]} Send-to-many: clone the template once per row, bind each role to its recipient, and send every envelope. Gated by sign.envelopes.send (it IS sending). A row is used only if it has a distinct email for every role in the template; incomplete rows are skipped.
envelope_id
string · path
/sign/templates/example/broadcasts
/decks/:id
Update a deck
PATCH /decks/:id. Title, content, thumbnail, or restore from trash.
id
string · path
title
string · min length: 1 · max length: 200
deck_json
object
slide_count
integer · min: 0 · max: 500
thumbnail_key
string · max length: 512
deleted
propertyName
anything
/decks/example
/decks
Create a deck
POST /decks. Create a blank deck.
title
string · min length: 1 · max length: 200
propertyName
anything
/decks
/decks/:id/assets
Register a deck image
POST /decks/:id/assets. Register an uploaded image. Gate loaded ctx.authz.deck.
id
string · path
asset_id
string · min length: 6 · max length: 64
storage_key
string · min length: 1 · max length: 512
filename
string · min length: 1 · max length: 255
content_type
string · min length: 1 · max length: 100
size_bytes
integer · min: 0
width
integer · min: 0
height
integer · min: 0
propertyName
anything
/decks/example/assets
/decks/:id/media
Add catalogue media to a deck
POST /decks/:id/media. Import a catalogue GIF into this deck. Its own sub-resource rather than a second shape of POST /decks/:id/assets: that route registers bytes the browser has already uploaded, this one makes the server go and fetch them. One schema each, one job each. The body carries a collection and a slug and nothing else. The URLs come back from KLIPY here, never from the caller, so there is no request a client can craft that points this fetch anywhere but the KLIPY CDN. Both objects land in the deck's own R2 prefix and become one ordinary slide_assets row, so from here on an imported GIF is cleaned up, presigned and permission-checked exactly like an uploaded photo. Gate loaded ctx.authz.deck.
id
string · path
collection
string · min length: 1 · max length: 20
slug
string · min length: 1 · max length: 200
propertyName
anything
/decks/example/media
/spellschemas
Introspect a platform API schema
Introspect a platform API endpoint's pytastic schema. POST /spellschemas with {route: "/tasks", method: "POST"} Returns UI-ready field definitions extracted from the TypedDict at runtime.
route
string · min length: 1
method
string
propertyName
anything
/spellschemas
/spell-runs/:run_id
undocumented /spell-runs/:run_id
run_id
string · path
/spell-runs/example
/spells/:spell_id
undocumented /spells/:spell_id
spell_id
string · path
/spells/example
/spells
undocumented /spells
/spells
/spells/:spell_id
undocumented /spells/:spell_id
spell_id
string · path
/spells/example
/spells/:spell_id/runs
undocumented /spells/:spell_id/runs
spell_id
string · path
/spells/example/runs
/spells
Create a spell
name
string · min length: 1 · max length: 200
description
string · max length: 2000
trigger
object
chain
array
enabled
format
source
string · max length: 100000
propertyName
anything
/spells
/spells/:spell_id/test
Test a spell (dry run)
Dry-run a spell with a sample event payload.
spell_id
string · path
payload
event_name
string
propertyName
anything
/spells/example/test
/wands/spellbook
Transform YAML <-> spell
Stateless YAML <-> spell transformer (no persistence). POST /wands/spellbook with {"source": "<yaml>"} -> {"spell": {...}} POST /wands/spellbook with {"spell": {...}} -> {"yaml": "..."} Lets the editor swap between the visual builder and the YAML view without saving. The engine still runs on stored JSON; this only reshapes in flight.
source
string · max length: 100000
spell
propertyName
anything
/wands/spellbook
/wands/schedule-previews
Check a schedule and preview its next runs
Validate a schedule and return the next few times it would fire. Always answers 200 with {valid: bool}: an author typing into the field gets a friendly message, not a stream of 422s.
text
string · min length: 1 · max length: 200
timezone
string · max length: 64
propertyName
anything
/wands/schedule-previews
/spells/:spell_id
Update a spell
spell_id
string · path
name
string · min length: 1 · max length: 200
description
string · max length: 2000
trigger
object
chain
array
enabled
format
source
string · max length: 100000
propertyName
anything
/spells/example
/tables/trash
undocumented /tables/trash
DELETE /tables/trash, permanently delete every trashed table the caller manages.
/tables/trash
/tables/trash/:table_id
undocumented /tables/trash/:table_id
DELETE /tables/trash/:table_id, permanently delete a trashed table.
table_id
string · path
/tables/trash/example
/tables/:table_id
undocumented /tables/:table_id
DELETE /tables/:table_id, move a table to the trash. Grants stay so it can be restored.
table_id
string · path
/tables/example
/tables/:table_id/sheets/:sheet_id
undocumented /tables/:table_id/sheets/:sheet_id
DELETE /tables/:table_id/sheets/:sheet_id — remove one sheet.
table_id
string · path
sheet_id
string · path
/tables/example/sheets/example
/tables
undocumented /tables
GET /tables — list tables for the workspace.
/tables
/tables/trash
undocumented /tables/trash
GET /tables/trash, the trashed tables the caller may restore.
/tables/trash
/tables/:table_id
undocumented /tables/:table_id
GET /tables/:table_id — get a single table with data.
table_id
string · path
/tables/example
/tables/:table_id/versions
undocumented /tables/:table_id/versions
GET /tables/:table_id/versions — list version history.
table_id
string · path
/tables/example/versions
/tables/:table_id/exports/:format
undocumented /tables/:table_id/exports/:format
GET /tables/:table_id/exports/:format: the workbook as an .ods download.
table_id
string · path
format
string · path
/tables/example/exports/example
/tables/:table_id/presence
undocumented /tables/:table_id/presence
GET /tables/:table_id/presence — get active collaborators.
table_id
string · path
/tables/example/presence
/tables/:table_id
Update a table
PATCH /tables/:table_id — update table title, icon, or data.
table_id
string · path
title
string · min length: 1 · max length: 500
icon
string · max length: 100
icon_type
data
string
visibility
deleted
propertyName
anything
/tables/example
/tables
Create a table
POST /tables — create a new table.
title
string · min length: 1 · max length: 500
icon
string · max length: 100
icon_type
data
string
propertyName
anything
/tables
/tables/:table_id/sheets/:sheet_id
Create or update a sheet
PUT /tables/:table_id/sheets/:sheet_id — create or update one sheet. The editor's debounced save PUTs only the sheets that actually changed, instead of PATCHing the whole workbook on every edit.
table_id
string · path
sheet_id
string · path
name
string · min length: 1 · max length: 200
position
integer · min: 0 · max: 500
doc
string
propertyName
anything
/tables/example/sheets/example
/tables/:table_id/presence
undocumented /tables/:table_id/presence
PUT /tables/:table_id/presence — update cursor position.
table_id
string · path
/tables/example/presence
/targets/:target_id
undocumented /targets/:target_id
target_id
string · path
/targets/example
/targets
undocumented /targets
/targets
/targets/leaderboard
undocumented /targets/leaderboard
/targets/leaderboard
/targets/:target_id
undocumented /targets/:target_id
target_id
string · path
/targets/example
/targets
Create a target
type
owner_mrn
string
pipeline_id
string
period
period_start
string
period_end
string
target_value
number
currency
string · min length: 3 · max length: 3
propertyName
anything
/targets
/targets/:target_id
Update a target
target_id
string · path
type
owner_mrn
string
period
period_start
string
period_end
string
target_value
number
currency
string · min length: 3 · max length: 3
status
propertyName
anything
/targets/example
/tasks/:task_id
undocumented /tasks/:task_id
task_id
string · path
/tasks/example
/tasks
Delete tasks in bulk
Delete multiple tasks by ID.
task_ids
array
propertyName
anything
/tasks
/tasks/:task_id/links/:link_id
undocumented /tasks/:task_id/links/:link_id
task_id
string · path
link_id
string · path
/tasks/example/links/example
/tasks
undocumented /tasks
/tasks
/tasks/:task_id
Update a task
task_id
string · path
title
string · min length: 1 · max length: 200
description
string · max length: 50000
column_name
string · min length: 1
assignee_mrn
string
reporter_mrn
string
reviewer_mrn
string
priority
topic_id
string
due_date
string
start_date
string
estimate_hours
logged_hours
wiki
string · max length: 200000
blocked_by
string
position
schedule_id
string
deliverable_id
string
parent_id
string
size
integer · min: 1
on_board
completed
labels
array
attachments
array
watchers
array
add_comment
object
propertyName
anything
/tasks/example
/tasks
Move tasks to another project
PATCH /tasks: move tasks to another board, each under that board's next key. Subtasks travel with their parent; sprint, deliverable and topic stay behind.
task_ids
array
board_id
string · min length: 1
columns
array
propertyName
anything
/tasks
/tasks
Create a task
title
string · min length: 1 · max length: 200
board_id
string
column_name
string · min length: 1
parent_id
string
on_board
priority
description
string · max length: 10000
topic_id
string
labels
array
attachments
array
assignee_mrn
string
schedule_id
string
due_date
string
size
integer · min: 1
source_mrn
string
propertyName
anything
/tasks
/tasks/:task_id/links
Link two tasks
POST /tasks/:task_id/links — relate this task to another (blocks/relates/duplicates).
task_id
string · path
to_task_id
string · min length: 1
kind
propertyName
anything
/tasks/example/links
/sign/templates
Create a reusable template
POST /sign/templates — create a reusable template.
title
string · min length: 1 · max length: 300
subject
string · max length: 300
message
string · max length: 2000
template_id
string
signing_order_mode
jurisdiction
string · max length: 10
is_template
source_mrn
string · max length: 200
propertyName
anything
/sign/templates
/sign/templates/:envelope_id/links
Publish the template as a self-serve link
POST /sign/templates/:envelope_id/links {expires_at?, max_submissions?} — publish the template as a URL anyone can open. Single-role templates only: the visitor fills that one role; multi-party agreements go through send.
envelope_id
string · path
expires_at
string
max_submissions
integer
propertyName
anything
/sign/templates/example/links
/tickits/:id
undocumented /tickits/:id
id
string · path
/tickits/example
/tickits
undocumented /tickits
/tickits
/tickits/days
undocumented /tickits/days
/tickits/days
/tickits/:id
Update a tickit
id
string · path
title
string · min length: 1 · max length: 140
due_on
string · max length: 10
urgency
completed
propertyName
anything
/tickits/example
/tickits
Add a tickit
title
string · min length: 1 · max length: 140
day
string · min length: 10 · max length: 10
propertyName
anything
/tickits
/boards/:board_id/topics/:topic_id
Rename a topic or change its dates
PATCH /boards/:board_id/topics/:topic_id: rename a topic or change its dates.
board_id
string · path
topic_id
string · path
name
string · min length: 1 · max length: 100
start_date
string
end_date
string
propertyName
anything
/boards/example/topics/example
/boards/:board_id/topics
Add a topic
POST /boards/:board_id/topics: add a topic to a board.
board_id
string · path
name
string · min length: 1 · max length: 100
start_date
string
end_date
string
propertyName
anything
/boards/example/topics
/totps/status
undocumented /totps/status
/totps/status
/totps
undocumented /totps
/totps
/trash
undocumented /trash
/trash
/trash
undocumented /trash
/trash
/trash/restorations
Restore from trash
ids
array
propertyName
anything
/trash/restorations
/vendibles/products/:product_id
undocumented /vendibles/products/:product_id
Archive, never delete. A product that has ever been sold is referenced by order line snapshots and by every movement in the ledger. Deleting the row would not remove those, it would only make them unreadable, so the delete verb archives.
product_id
string · path
/vendibles/products/example
/vendibles/products/:product_id/variants/:variant_id
undocumented /vendibles/products/:product_id/variants/:variant_id
Deactivate a variant. The last one, and the default, cannot go. Deactivating rather than deleting for the same reason products archive: the ledger and every order line point at this id forever.
product_id
string · path
variant_id
string · path
/vendibles/products/example/variants/example
/vendibles/collections/:collection_id
undocumented /vendibles/collections/:collection_id
A collection is merchandising, not inventory, so it really does delete. Nothing references it: membership lives on this row, and removing it takes no product with it.
collection_id
string · path
/vendibles/collections/example
/vendibles/locations/:location_id
undocumented /vendibles/locations/:location_id
Deactivate a location. Refuses while anything is still standing in it. Deactivating a place that holds stock would make that stock invisible while leaving it counted, which is the worst of both.
location_id
string · path
/vendibles/locations/example
/vendibles/domains/:domain_id
undocumented /vendibles/domains/:domain_id
domain_id
string · path
/vendibles/domains/example
/vendibles/storefront/logo
undocumented /vendibles/storefront/logo
DELETE /vendibles/storefront/logo — take the mark off the shop. The header falls back to the shop's name set in the display face, which is a deliberate design rather than an empty space: a shop with no logo should still look like it was designed by somebody.
/vendibles/storefront/logo
/vendibles/products/:product_id/images/:image_id
undocumented /vendibles/products/:product_id/images/:image_id
DELETE /vendibles/products/:product_id/images/:image_id — drop one. Deletes the object as well as the reference. "Remove this picture" has to mean it stops being served, not merely that the shop stops pointing at it.
product_id
string · path
image_id
string · path
/vendibles/products/example/images/example
/vendibles/collections/:collection_id/image
undocumented /vendibles/collections/:collection_id/image
DELETE /vendibles/collections/:collection_id/image — take it down.
collection_id
string · path
/vendibles/collections/example/image
/vendibles/products
undocumented /vendibles/products
/vendibles/products
/vendibles/products/:product_id
undocumented /vendibles/products/:product_id
product_id
string · path
/vendibles/products/example
/vendibles/collections
undocumented /vendibles/collections
/vendibles/collections
/vendibles/collections/:collection_id
undocumented /vendibles/collections/:collection_id
collection_id
string · path
/vendibles/collections/example
/vendibles/locations/tree
undocumented /vendibles/locations/tree
The whole tree, nested. Bounded by the number of places a merchant has. Unpaginated on purpose: a tree with a page break is not a tree, and the row count here is physical places, which does not grow the way a catalog does.
/vendibles/locations/tree
/vendibles/locations
undocumented /vendibles/locations
/vendibles/locations
/vendibles/stock
undocumented /vendibles/stock
/vendibles/stock
/vendibles/exports
undocumented /vendibles/exports
The ledger as a CSV, narrowed by exactly the filters the screen uses. Reads its filters through the same helpers the list and the console read, so what a merchant exports is what they were looking at. An export built on its own filter parsing is an export that quietly disagrees with the screen above it, which is the worst kind of wrong: nobody checks a spreadsheet against the page it came from. Names are resolved rather than exported as ids, and the reference is the readable label. An id is useless in a spreadsheet and an MRN doubly so.
/vendibles/exports
/vendibles/movements
undocumented /vendibles/movements
/vendibles/movements
/vendibles/orders
undocumented /vendibles/orders
/vendibles/orders
/vendibles/orders/:order_id
undocumented /vendibles/orders/:order_id
order_id
string · path
/vendibles/orders/example
/vendibles/domains
undocumented /vendibles/domains
/vendibles/domains
/vendibles/orders/:order_id
Mark an order fulfilled, or cancel an unpaid one
Fulfil or cancel. A status field, never a verb route (rule 15).
order_id
string · path
status
fulfillment
object
propertyName
anything
/vendibles/orders/example
/vendibles/domains/:domain_id
Ask for a domain's claim once its DNS record is published
Ask for the claim. The DNS record is what grants it, not this call. A status transition rather than a verb endpoint (rule 15). The only transition a person can ask for is pending to verified, and asking is not the same as getting: the TXT record has to actually resolve, and the partial unique index decides who wins if two workspaces ask at once.
domain_id
string · path
status
propertyName
anything
/vendibles/domains/example
/vendibles/products
Create a product and its default variant
kind
name
string · min length: 1 · max length: 200
slug
string · min length: 1 · max length: 120
description
string · max length: 20000
options
array
images
array
unit_of_measure
string · min length: 1 · max length: 32
is_stockable
status
show_in_store
seo
object
metadata
object
price
number
sku
string · min length: 1 · max length: 64
propertyName
anything
/vendibles/products
/vendibles/products/:product_id/variants
Add a variant to a product
product_id
string · path
option_values
sku
string · min length: 1 · max length: 64
barcode
string · min length: 1 · max length: 64
price
number
compare_at_price
number
cost_price
number
position
integer · min: 0 · max: 999
is_default
is_active
metadata
object
opening_quantity
number · min: 0
opening_location_id
string · min length: 1 · max length: 100
propertyName
anything
/vendibles/products/example/variants
/vendibles/collections
Create a merchandising collection
name
string · min length: 1 · max length: 200
parent_id
string · max length: 100
slug
string · min length: 1 · max length: 120
description
string · max length: 4000
image_mrn
string · max length: 200
product_ids
array
position
integer · min: 0 · max: 999
is_visible
propertyName
anything
/vendibles/collections
/vendibles/locations
Create a stock location
name
string · min length: 1 · max length: 120
timezone
string · min length: 1 · max length: 64
workdays
work_start
string · max length: 5
work_end
string · max length: 5
is_default
propertyName
anything
/vendibles/locations
/vendibles/movements
Post a stock movement
Post one ledger entry and move the on-hand it implies. The order matters: validate everything first, then write the ledger row, then apply the effects. A movement that was refused must leave no trace, and a movement that was accepted must never exist without its stock change.
variant_id
string · min length: 1 · max length: 100
quantity
number
reason
from_location_id
string · min length: 1 · max length: 100
to_location_id
string · min length: 1 · max length: 100
unit_cost
number
reference_mrn
string · min length: 1 · max length: 200
occurred_at
string · min length: 1 · max length: 60
notes
string · max length: 2000
propertyName
anything
/vendibles/movements
/vendibles/transfers
Move many variants between two places
Move many variants from one place to another, as one action. One `transfer` movement per line, each carrying both ends, which is the ledger's existing shape for a move and not a new one. The sheet is the multi-line thing; the movement is not.
from_location_id
string · min length: 1 · max length: 100
to_location_id
string · min length: 1 · max length: 100
lines
array
occurred_at
string · min length: 1 · max length: 60
notes
string · max length: 2000
propertyName
anything
/vendibles/transfers
/vendibles/counts
Record a physical count at one place
Record what was actually found on the shelf, for many variants at once. A count states a total rather than a change, so each line posts a `count` movement carrying the counted figure and the stock effect is a set. Lines already agreeing with the system are skipped: a ledger entry recording that nothing changed is noise in the one record that has to stay readable.
location_id
string · min length: 1 · max length: 100
lines
array
occurred_at
string · min length: 1 · max length: 60
notes
string · max length: 2000
propertyName
anything
/vendibles/counts
/vendibles/domains
Add a domain to point at the store
hostname
string · min length: 4 · max length: 253
propertyName
anything
/vendibles/domains
/vendibles/products/:product_id/images
undocumented /vendibles/products/:product_id/images
POST /vendibles/products/:product_id/images — add a photograph. Multipart, because it carries a file. Appends rather than replaces: a product has several shots and the merchant decides the order.
product_id
string · path
/vendibles/products/example/images
/vendibles/products/:product_id
Update a product
product_id
string · path
name
string · min length: 1 · max length: 200
slug
string · min length: 1 · max length: 120
description
string · max length: 20000
options
array
images
array
unit_of_measure
string · min length: 1 · max length: 32
is_stockable
status
show_in_store
seo
object
metadata
object
propertyName
anything
/vendibles/products/example
/vendibles/products/:product_id/variants/:variant_id
Update a variant
product_id
string · path
variant_id
string · path
option_values
sku
string · min length: 1 · max length: 64
barcode
string · min length: 1 · max length: 64
price
number
compare_at_price
number
cost_price
number
position
integer · min: 0 · max: 999
is_default
is_active
metadata
object
propertyName
anything
/vendibles/products/example/variants/example
/vendibles/collections/:collection_id
Update a collection, including its merchandising order
collection_id
string · path
name
string · min length: 1 · max length: 200
parent_id
string · max length: 100
slug
string · min length: 1 · max length: 120
description
string · max length: 4000
image_mrn
string · max length: 200
icon
string · max length: 60
product_ids
array
position
integer · min: 0 · max: 999
is_visible
propertyName
anything
/vendibles/collections/example
/vendibles/locations/:location_id
Update or move a location
location_id
string · path
name
string · min length: 1 · max length: 120
timezone
string · min length: 1 · max length: 64
workdays
work_start
string · max length: 5
work_end
string · max length: 5
is_default
propertyName
anything
/vendibles/locations/example
/vendibles/stock/:stock_id/reorder-point
Set or clear a reorder point
stock_id
string · path
reorder_point
number
propertyName
anything
/vendibles/stock/example/reorder-point
/vendibles/storefront/theme
Set the shop's colours, typeface pairing and control shape
PUT /vendibles/storefront/theme — the shop's colours, type and shape. Three of the merchant's four choices. The fourth is the logo below, which needs its own route because it carries a file. The typeset and the button style are validated against the tables in helpers rather than trusted: the schema's Literal already refuses an unknown value, and this refuses it a second time with a message naming what IS allowed, because a shopper never sees this error and a merchant does.
typeset
button_style
fluid
colors
object
propertyName
anything
/vendibles/storefront/theme
/vendibles/storefront/logo
undocumented /vendibles/storefront/logo
PUT /vendibles/storefront/logo — the mark in the shop's header. Multipart rather than JSON, because it is a file. The key is reused across replacements so one workspace keeps one object and one stable URL; the shared helper explains why that matters more than it looks.
/vendibles/storefront/logo
/vendibles/products/:product_id/images
Set the order a product's pictures appear in
PUT /vendibles/products/:product_id/images — set the order. A PUT on the collection with the ids in the order wanted, rather than a /cover endpoint: making a picture the cover IS reordering it to the front, and two ways to express one fact eventually disagree.
product_id
string · path
order
array
propertyName
anything
/vendibles/products/example/images
/vendibles/collections/:collection_id/image
undocumented /vendibles/collections/:collection_id/image
PUT /vendibles/collections/:collection_id/image — the shop-window shot. One picture, not a list: a collection card shows exactly one, and offering several would be offering a choice that never reaches a shopper.
collection_id
string · path
/vendibles/collections/example/image
/verifications/resend
undocumented /verifications/resend
/verifications/resend
/views/:view_id
undocumented /views/:view_id
view_id
string · path
/views/example
/views
undocumented /views
/views
/wands/events
undocumented /wands/events
List all platform events available as flow triggers.
/wands/events
/wands/filters
undocumented /wands/filters
List all registered Jinja2 filters with descriptions.
/wands/filters
/wands/context/:spell_id/:step_index
undocumented /wands/context/:spell_id/:step_index
Get available context variables for a given step in a spell's chain.
spell_id
string · path
step_index
string · path
/wands/context/example/example
/wands/macros
undocumented /wands/macros
All macros. ?grouped=true returns them in category order with Spellbook-rendered examples (what the reference page renders).
/wands/macros
/wands/macros/:macro_name
undocumented /wands/macros/:macro_name
macro_name
string · path
/wands/macros/example
/wands/samples
undocumented /wands/samples
Recent REAL payloads captured in this workspace. With ?action=core.crm.deal.won: every stored sample for that event. Without it: the latest sample for each event seen, so the builder and the macro playground can offer a menu of real payloads to try.
/wands/samples
/wands/recipes
undocumented /wands/recipes
Curated recipe gallery, filtered to the workspace's installed apps.
/wands/recipes
/wands/stats
undocumented /wands/stats
Workspace automation dashboard payload.
/wands/stats
/wiki/trash
undocumented /wiki/trash
DELETE /wiki/trash: delete for good every trashed page in a space the caller may purge.
/wiki/trash
/wiki/trash/:page_id
undocumented /wiki/trash/:page_id
DELETE /wiki/trash/:page_id: delete a trashed page for good and free its storage now.
page_id
string · path
/wiki/trash/example
/wiki/spaces/:space_id
undocumented /wiki/spaces/:space_id
DELETE /wiki/spaces/:space_id: remove an empty space. General cannot be removed.
space_id
string · path
/wiki/spaces/example
/wiki/tree
undocumented /wiki/tree
GET /wiki/tree — get the full page tree for the workspace.
/wiki/tree
/wiki/trash
undocumented /wiki/trash
GET /wiki/trash: pages in the trash the caller may restore or delete for good.
/wiki/trash
/wiki/share-roles
undocumented /wiki/share-roles
GET /wiki/share-roles — roles a member may add to a page share list.
/wiki/share-roles
/wiki/spaces
undocumented /wiki/spaces
GET /wiki/spaces: every space in the workspace, General first.
/wiki/spaces
/wiki/spaces/:space_id
undocumented /wiki/spaces/:space_id
GET /wiki/spaces/:space_id: one space.
space_id
string · path
/wiki/spaces/example
/wikis/:page_id
Update a wiki page
PATCH /wikis/:page_id — update page title, content, icon, etc.
page_id
string · path
deleted
title
string · min length: 1 · max length: 500
icon
string · max length: 100
icon_type
content
string
position
integer · min: 0
parent_id
string
cover
string · max length: 200
status
reviewers
array
target_date
string · max length: 10
team
string · max length: 120
properties
array
tags
array
kind
columns
array
propertyName
anything
/wikis/example
/wiki/spaces/:space_id
Update a wiki space
PATCH /wiki/spaces/:space_id: rename, describe or reorder a space.
space_id
string · path
name
string · min length: 1 · max length: 120
description
string · max length: 500
position
integer · min: 0
propertyName
anything
/wiki/spaces/example
/wikis/:page_id/comments/:comment_id
Resolve/unresolve comment
PATCH /wikis/:page_id/comments/:comment_id — resolve or unresolve.
page_id
string · path
comment_id
string · path
resolved
propertyName
anything
/wikis/example/comments/example
/wikis/:page_id/subscription
Star or watch a page
PATCH /wikis/:page_id/subscription: the caller's own star and watch on the page.
page_id
string · path
starred
watching
propertyName
anything
/wikis/example/subscription
/wikis/:page_id/rows/:row_id
Update a database row
PATCH /wikis/:page_id/rows/:row_id: change cells or reorder a row.
page_id
string · path
row_id
string · path
cells
array
position
integer · min: 0
propertyName
anything
/wikis/example/rows/example
/wikis
Create a wiki page
POST /wikis — create a new wiki page.
title
string · min length: 1 · max length: 500
parent_id
string
space_id
string · max length: 100
kind
icon
string · max length: 100
icon_type
content
string
template_id
string · max length: 100
propertyName
anything
/wikis
/wiki/spaces
Create a wiki space
POST /wiki/spaces: a new team space.
name
string · min length: 1 · max length: 120
description
string · max length: 500
kind
propertyName
anything
/wiki/spaces
/wikis/:page_id/comments
Add a comment
POST /wikis/:page_id/comments — add a comment.
page_id
string · path
body
string · min length: 1 · max length: 4000
object_id
string · max length: 64
parent_id
string · max length: 64
nx
number
ny
number
propertyName
anything
/wikis/example/comments
/wikis/:page_id/reactions
Like a page
POST /wikis/:page_id/reactions: the caller likes the page. Liking twice is one like.
page_id
string · path
kind
propertyName
anything
/wikis/example/reactions
/wikis/:page_id/rows
Add a database row
POST /wikis/:page_id/rows: a new row at the end of a database page.
page_id
string · path
cells
array
position
integer · min: 0
propertyName
anything
/wikis/example/rows
/wikis/:page_id/media
Attach an uploaded picture or video to a page
POST /wikis/:page_id/media: register bytes uploaded into the wiki's namespace as a picture or video on this page.
page_id
string · path
key
string · min length: 1 · max length: 1024
filename
string · max length: 255
content_type
string · max length: 100
size_bytes
integer · min: 0
propertyName
anything
/wikis/example/media
/wikis/:page_id/position
Move/reorder a page
PUT /wikis/:page_id/position — move a page to a new parent/position.
page_id
string · path
parent_id
string
position
integer · min: 0
space_id
string · max length: 100
propertyName
anything
/wikis/example/position
/wikis/:page_id/access
Change page visibility and share list
PUT /wikis/:page_id/access — change visibility and share list. Requires manage-level access (authz: can_manage_page).
page_id
string · path
visibility
shares
array
propertyName
anything
/wikis/example/access
/wikis/:page_id/publication
Publish or unpublish a page for the help widget
PUT /wikis/:page_id/publication: expose or withdraw one page. Requires manage-level access (authz: can_manage_page), the same gate as the share list: publishing puts the page in front of anyone holding the help widget's link, which is a bigger decision than editing it. Publication is per page and is NEVER inherited. Publishing a parent does nothing to its children, which is what stops an internal page becoming public the first time somebody reparents it under a published root. Being published is not the same as being reachable: a page is served to a visitor only when its subtree root also carries external_ref, which only the contacts link event sets. A workspace can therefore prepare a base and publish pages before any widget exists, and nothing is exposed until it links one.
page_id
string · path
is_published
propertyName
anything
/wikis/example/publication
/wikis/:page_id
undocumented /wikis/:page_id
DELETE /wikis/:page_id — soft-delete a page and its descendants.
page_id
string · path
/wikis/example
/wikis/:page_id/comments/:comment_id
undocumented /wikis/:page_id/comments/:comment_id
DELETE /wikis/:page_id/comments/:comment_id — delete a comment.
page_id
string · path
comment_id
string · path
/wikis/example/comments/example
/wikis/:page_id/reactions/:kind
undocumented /wikis/:page_id/reactions/:kind
DELETE /wikis/:page_id/reactions/:kind: the caller takes their like back.
page_id
string · path
kind
string · path
/wikis/example/reactions/example
/wikis/:page_id/rows/:row_id
undocumented /wikis/:page_id/rows/:row_id
DELETE /wikis/:page_id/rows/:row_id: remove a row.
page_id
string · path
row_id
string · path
/wikis/example/rows/example
/wikis/:page_id/media/:media_id
undocumented /wikis/:page_id/media/:media_id
DELETE /wikis/:page_id/media/:media_id: take a picture or video and its bytes off the page.
page_id
string · path
media_id
string · path
/wikis/example/media/example
/wikis
undocumented /wikis
GET /wikis — list root-level pages. Restricted pages the caller cannot access are filtered out at query time. Owners/admins see everything (platform bypass).
/wikis
/wikis/:page_id
undocumented /wikis/:page_id
GET /wikis/:page_id — get a single page with content.
page_id
string · path
/wikis/example
/wikis/:page_id/children
undocumented /wikis/:page_id/children
GET /wikis/:page_id/children — list child pages. Filters out restricted children the caller cannot access.
page_id
string · path
/wikis/example/children
/wikis/:page_id/backlinks
undocumented /wikis/:page_id/backlinks
GET /wikis/:page_id/backlinks: the pages whose content links to this one. Filtered by the caller's visibility, so a restricted page never reveals itself here.
page_id
string · path
/wikis/example/backlinks
/wikis/:page_id/versions
undocumented /wikis/:page_id/versions
GET /wikis/:page_id/versions — list version history.
page_id
string · path
/wikis/example/versions
/wikis/:page_id/versions/:version_id
undocumented /wikis/:page_id/versions/:version_id
GET /wikis/:page_id/versions/:version_id — get a single version.
page_id
string · path
version_id
string · path
/wikis/example/versions/example
/wikis/:page_id/comments
undocumented /wikis/:page_id/comments
GET /wikis/:page_id/comments — list comments for a page.
page_id
string · path
/wikis/example/comments
/wikis/:page_id/presence
undocumented /wikis/:page_id/presence
GET /wikis/:page_id/presence — get active collaborators.
page_id
string · path
/wikis/example/presence
/wikis/:page_id/rows
undocumented /wikis/:page_id/rows
GET /wikis/:page_id/rows: the rows of a database page, in order, with their columns.
page_id
string · path
/wikis/example/rows
/wikis/:page_id/media/:media_id
undocumented /wikis/:page_id/media/:media_id
GET /wikis/:page_id/media/:media_id: a short-lived playback link for a reader of the page.
page_id
string · path
media_id
string · path
/wikis/example/media/example
/wikis/:page_id/views
undocumented /wikis/:page_id/views
POST /wikis/:page_id/views: the caller opened the page. One row per person, counted up.
page_id
string · path
/wikis/example/views
/wikis/:page_id/presence
undocumented /wikis/:page_id/presence
PUT /wikis/:page_id/presence — update cursor position.
page_id
string · path
/wikis/example/presence
/workers/:worker_id/documents/:document_id
Move or rename a worker document
Move a document between folders (and to/from root), or rename it.
worker_id
string · path
document_id
string · path
title
string · min length: 1 · max length: 500
icon
string · max length: 100
icon_type
content
string
is_starred
page_mode
visibility
page_setup
object
deleted
propertyName
anything
/workers/example/documents/example
/workers/:worker_id/documents/folders
Create a document folder
worker_id
string · path
name
string · min length: 1 · max length: 120
propertyName
anything
/workers/example/documents/folders
/workers/:worker_id/documents
Record an uploaded worker document
Record a document the browser already uploaded to R2 (Computer source).
worker_id
string · path
title
string · min length: 1 · max length: 500
icon
string · max length: 100
icon_type
content
string
propertyName
anything
/workers/example/documents
/workers/:worker_id/notes
Add a note to a worker
worker_id
string · path
text
string · min length: 1 · max length: 5000
propertyName
anything
/workers/example/notes
/workers/:worker_id/notes/:note_id
Update a worker note
worker_id
string · path
note_id
string · path
text
string · min length: 1 · max length: 5000
propertyName
anything
/workers/example/notes/example
/workers/:worker_id/personal
Update personal details
PATCH personal details — merge provided keys; empty string clears a key.
worker_id
string · path
date_of_birth
string · max length: 10
gender
string · max length: 50
pronouns
string · max length: 50
nationality
string · max length: 100
marital_status
string · max length: 50
personal_email
string · max length: 200
personal_phone
string · max length: 50
address_line1
string · max length: 200
address_line2
string · max length: 200
city
string · max length: 100
state
string · max length: 100
postal_code
string · max length: 30
country
string · max length: 100
propertyName
anything
/workers/example/personal
/workers/:worker_id/qualifications
Update qualifications
PATCH qualifications — each provided collection replaces that collection.
worker_id
string · path
education
array
certifications
array
skills
array
languages
array
propertyName
anything
/workers/example/qualifications
/workers/:worker_id/bank-details
Update bank details
PATCH bank details — merge flat fields; identifiers list replaces whole.
worker_id
string · path
bank_name
string · max length: 150
account_name
string · max length: 150
account_number
string · max length: 50
branch_code
string · max length: 50
iban
string · max length: 50
swift_bic
string · max length: 20
currency
string · max length: 3
notes
string · max length: 500
identifiers
array
propertyName
anything
/workers/example/bank-details
/workers/:worker_id/emergency-contacts
Replace emergency contacts
PUT the full emergency contacts list (replace semantics).
worker_id
string · path
contacts
array
propertyName
anything
/workers/example/emergency-contacts
/workers/:worker_id/right-to-work
Replace right-to-work documents
PUT the full right-to-work document list (replace semantics).
worker_id
string · path
records
array
propertyName
anything
/workers/example/right-to-work
/workers/:worker_id
undocumented /workers/:worker_id
worker_id
string · path
/workers/example
/workers/fields/:field_id
undocumented /workers/fields/:field_id
field_id
string · path
/workers/fields/example
/workers/:worker_id/notes/:note_id
undocumented /workers/:worker_id/notes/:note_id
worker_id
string · path
note_id
string · path
/workers/example/notes/example
/workers/:worker_id/employment/:record_id
undocumented /workers/:worker_id/employment/:record_id
worker_id
string · path
record_id
string · path
/workers/example/employment/example
/workers/:worker_id/documents/folders/:folder_id
undocumented /workers/:worker_id/documents/folders/:folder_id
worker_id
string · path
folder_id
string · path
/workers/example/documents/folders/example
/workers/:worker_id/documents/:document_id
undocumented /workers/:worker_id/documents/:document_id
worker_id
string · path
document_id
string · path
/workers/example/documents/example
/workers
undocumented /workers
/workers
/workers/:worker_id
undocumented /workers/:worker_id
worker_id
string · path
/workers/example
/workers/:worker_id/routes
undocumented /workers/:worker_id/routes
Where a worker went while clocked in on ?day=YYYY-MM-DD, that day being the worker's own location's.
worker_id
string · path
/workers/example/routes
/workers/locations/:location_id/members
undocumented /workers/locations/:location_id/members
Workers currently assigned to a location — powers the delete dialog count.
location_id
string · path
/workers/locations/example/members
/workers/fields
undocumented /workers/fields
/workers/fields
/workers/:worker_id/fields
undocumented /workers/:worker_id/fields
Field definitions merged with this worker's values. Sensitive-flagged fields are omitted entirely unless the caller holds workers.sensitive.*.
worker_id
string · path
/workers/example/fields
/workers/:worker_id/personal
undocumented /workers/:worker_id/personal
Personal profile bundle: personal details, emergency contacts, right to work, qualifications (all gated on workers.personal.*).
worker_id
string · path
/workers/example/personal
/workers/:worker_id/bank-details
undocumented /workers/:worker_id/bank-details
Bank details + identity numbers (gated on workers.sensitive.*).
worker_id
string · path
/workers/example/bank-details
/workers/:worker_id/notes
undocumented /workers/:worker_id/notes
worker_id
string · path
/workers/example/notes
/workers/:worker_id/compensation
undocumented /workers/:worker_id/compensation
worker_id
string · path
/workers/example/compensation
/workers/:worker_id/employment
undocumented /workers/:worker_id/employment
worker_id
string · path
/workers/example/employment
/workers/:worker_id/documents
undocumented /workers/:worker_id/documents
worker_id
string · path
/workers/example/documents
/workers/:worker_id/documents/:document_id/view
undocumented /workers/:worker_id/documents/:document_id/view
Short-lived presigned GET URL for a worker document.
worker_id
string · path
document_id
string · path
/workers/example/documents/example/view
/workers/:worker_id
Update a worker profile
worker_id
string · path
full_name
string · min length: 1 · max length: 200
employee_id
string · max length: 50
department_id
string
manager_id
string
status
location_mrn
string · max length: 120
work_location
string · max length: 200
work_mode
expected_hours_per_day
number
work_email
string · max length: 200
work_phone
string · max length: 50
notes
string · max length: 5000
propertyName
anything
/workers/example
/workers
Create a worker profile
member_mrn
string · min length: 1
full_name
string · max length: 200
job_title
string · min length: 1 · max length: 200
hire_date
string · min length: 1
employee_id
string · max length: 50
department_id
string
manager_id
string
employment_type
status
location_mrn
string · max length: 120
work_location
string · max length: 200
work_mode
expected_hours_per_day
number
work_email
string · max length: 200
work_phone
string · max length: 50
notes
string · max length: 5000
propertyName
anything
/workers
/workers/locations/:location_id/reassignment
Reassign workers off a location
Move every worker assigned to a location to another one (or clear it). Body: {"target": "<location mrn>"} to move, or omit/empty to set to none. Called by the location delete dialog before the location is removed.
location_id
string · path
target
string
propertyName
anything
/workers/locations/example/reassignment
/workspaces/:id
Delete workspace
DELETE /workspaces/:id: lock the workspace and delete it permanently after the hold. Owner only.
id
string · path
confirmation
string · min length: 1
propertyName
anything
/workspaces/example
/workspaces/current
undocumented /workspaces/current
GET /workspaces/current: the caller's workspace as the row says it is now. The session carries the slug as it was at sign-in, which goes stale the moment an admin renames the workspace under a member's open tab. The waiting page polls this to learn the new address, so it answers from the row, never from the session.
/workspaces/current
/ws/ws
Platform WebSocket handler — authenticates via session and holds connection open.
/calls/ws/calls/ws
WebSocket handler for call signaling and state updates.