Saaslivery API

v1.0.0 · 1062 endpoints · 2 websockets
DELETE /totps

Disable 2FA

Handled by disable_totp
Body · DisableTotpapplication/json
password string · min length: 1
required
propertyName anything
Responses
200Successful Response
DELETE /totps
1curl -X DELETE "http://localhost:8000/totps" \
2 -H "Content-Type: application/json" \
3 -d '{"password":"string"}'
1fetch("http://localhost:8000/totps", {
2 method: "DELETE",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "password": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.delete(
4 "http://localhost:8000/totps",
5 json={"password":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /totps

Verify code and enable 2FA

Handled by enable_totp
Body · EnableTotpapplication/json
code string · min length: 6 · max length: 6
required
propertyName anything
Responses
200Successful Response
PUT /totps
1curl -X PUT "http://localhost:8000/totps" \
2 -H "Content-Type: application/json" \
3 -d '{"code":"string"}'
1fetch("http://localhost:8000/totps", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "code": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/totps",
5 json={"code":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /ai/commands

Ask about the current app

POST /ai/commands — answer a question about the app the member is in.

Handled by api_command
Body · AskWorkspaceapplication/json
app string · min length: 1 · max length: 64
required
q string · min length: 1 · max length: 2000
required
propertyName anything
Responses
200Successful Response
POST /ai/commands
1curl -X POST "http://localhost:8000/ai/commands" \
2 -H "Content-Type: application/json" \
3 -d '{"app":"string","q":"string"}'
1fetch("http://localhost:8000/ai/commands", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "app": "string",
6 "q": "string"
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/ai/commands",
5 json={"app":"string","q":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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.

Handled by api_create_api_key
Body · CreateApiKeyapplication/json
name string · min length: 1 · max length: 100
required
full_access
scopes array
expires_at string · max length: 40
propertyName anything
Responses
200Successful Response
POST /api-keys
1curl -X POST "http://localhost:8000/api-keys" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","full_access":null,"scopes":["string"],"expires_at":"string"}'
1fetch("http://localhost:8000/api-keys", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "full_access": null,
7 "scopes": [
8 "string"
9 ],
10 "expires_at": "string"
11}),
12})
13 .then((res) => res.json())
14 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/api-keys",
5 json={"name":"string","full_access":null,"scopes":["string"],"expires_at":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /api-keys/:key_id

Update or revoke API key

PUT /api-keys/:key_id: rename, re-scope, or revoke a key.

Handled by api_update_api_key
Parameters
key_id string · path
required
Body · UpdateApiKeyapplication/json
name string · min length: 1 · max length: 100
full_access
scopes array
status
expires_at string · max length: 40
never_expires
propertyName anything
Responses
200Successful Response
PUT /api-keys/example
1curl -X PUT "http://localhost:8000/api-keys/example" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","full_access":null,"scopes":["string"],"status":null,"expires_at":"string","never_expires":null}'
1fetch("http://localhost:8000/api-keys/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "full_access": null,
7 "scopes": [
8 "string"
9 ],
10 "status": null,
11 "expires_at": "string",
12 "never_expires": null
13}),
14})
15 .then((res) => res.json())
16 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/api-keys/example",
5 json={"name":"string","full_access":null,"scopes":["string"],"status":null,"expires_at":"string","never_expires":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /api-keys/:key_id/secret

Rotate API key secret

PUT /api-keys/:key_id/secret: replace the secret; old one dies now.

Handled by api_rotate_api_key
Parameters
key_id string · path
required
Body · RotateApiKeyapplication/json
expires_at string · max length: 40
never_expires
propertyName anything
Responses
200Successful Response
PUT /api-keys/example/secret
1curl -X PUT "http://localhost:8000/api-keys/example/secret" \
2 -H "Content-Type: application/json" \
3 -d '{"expires_at":"string","never_expires":null}'
1fetch("http://localhost:8000/api-keys/example/secret", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "expires_at": "string",
6 "never_expires": null
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/api-keys/example/secret",
5 json={"expires_at":"string","never_expires":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /ats/jobs/:job_id/status

Move a job between draft, approval, open, hold and closed

Handled by api_update_job_status
Parameters
job_id string · path
required
Body · UpdateJobStatusapplication/json
status
required
reason string · max length: 1000
propertyName anything
Responses
200Successful Response
PATCH /ats/jobs/example/status
1curl -X PATCH "http://localhost:8000/ats/jobs/example/status" \
2 -H "Content-Type: application/json" \
3 -d '{"status":null,"reason":"string"}'
1fetch("http://localhost:8000/ats/jobs/example/status", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "status": null,
6 "reason": "string"
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/ats/jobs/example/status",
5 json={"status":null,"reason":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /ats/stages/:stage_id/position

Reorder a stage

Handled by api_stage_position
Parameters
stage_id string · path
required
Body · StagePositionapplication/json
position integer · min: 0 · max: 999
required
propertyName anything
Responses
200Successful Response
PATCH /ats/stages/example/position
1curl -X PATCH "http://localhost:8000/ats/stages/example/position" \
2 -H "Content-Type: application/json" \
3 -d '{"position":1}'
1fetch("http://localhost:8000/ats/stages/example/position", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "position": 1
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/ats/stages/example/position",
5 json={"position":1},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /ats/applications/:application_id/stage

Move an application to another stage

Handled by api_move_application_stage
Parameters
application_id string · path
required
Body · MoveApplicationStageapplication/json
stage_id string · min length: 1 · max length: 100
required
note string · max length: 2000
propertyName anything
Responses
200Successful Response
PATCH /ats/applications/example/stage
1curl -X PATCH "http://localhost:8000/ats/applications/example/stage" \
2 -H "Content-Type: application/json" \
3 -d '{"stage_id":"string","note":"string"}'
1fetch("http://localhost:8000/ats/applications/example/stage", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "stage_id": "string",
6 "note": "string"
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/ats/applications/example/stage",
5 json={"stage_id":"string","note":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /ats/applications/:application_id/status

Reject, hire, hold, withdraw or reopen an application

Handled by api_update_application_status
Parameters
application_id string · path
required
Body · UpdateApplicationStatusapplication/json
status
required
rejection_reason string · max length: 1000
notify_candidate
template_id string · max length: 100
propertyName anything
Responses
200Successful Response
PATCH /ats/applications/example/status
1curl -X PATCH "http://localhost:8000/ats/applications/example/status" \
2 -H "Content-Type: application/json" \
3 -d '{"status":null,"rejection_reason":"string","notify_candidate":null,"template_id":"string"}'
1fetch("http://localhost:8000/ats/applications/example/status", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "status": null,
6 "rejection_reason": "string",
7 "notify_candidate": null,
8 "template_id": "string"
9}),
10})
11 .then((res) => res.json())
12 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/ats/applications/example/status",
5 json={"status":null,"rejection_reason":"string","notify_candidate":null,"template_id":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /ats/interviews/:interview_id/schedule

Put an interview on the calendar, or move it

Handled by api_schedule_interview
Parameters
interview_id string · path
required
Body · ScheduleInterviewapplication/json
scheduled_at string · min length: 1 · max length: 40
required
duration_minutes integer · min: 5 · max: 600
location string · max length: 500
instructions string · max length: 5000
propertyName anything
Responses
200Successful Response
PATCH /ats/interviews/example/schedule
1curl -X PATCH "http://localhost:8000/ats/interviews/example/schedule" \
2 -H "Content-Type: application/json" \
3 -d '{"scheduled_at":"string","duration_minutes":1,"location":"string","instructions":"string"}'
1fetch("http://localhost:8000/ats/interviews/example/schedule", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "scheduled_at": "string",
6 "duration_minutes": 1,
7 "location": "string",
8 "instructions": "string"
9}),
10})
11 .then((res) => res.json())
12 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/ats/interviews/example/schedule",
5 json={"scheduled_at":"string","duration_minutes":1,"location":"string","instructions":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /ats/offers/:offer_id/status

Move an offer between draft, approval, approved, sent and rescinded

Handled by api_update_offer_status
Parameters
offer_id string · path
required
Body · UpdateOfferStatusapplication/json
status
required
reason string · max length: 1000
propertyName anything
Responses
200Successful Response
PATCH /ats/offers/example/status
1curl -X PATCH "http://localhost:8000/ats/offers/example/status" \
2 -H "Content-Type: application/json" \
3 -d '{"status":null,"reason":"string"}'
1fetch("http://localhost:8000/ats/offers/example/status", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "status": null,
6 "reason": "string"
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/ats/offers/example/status",
5 json={"status":null,"reason":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /ats/jobs

Create a job

Handled by api_create_job
Body · CreateJobapplication/json
title string · min length: 1 · max length: 200
required
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
Responses
200Successful Response
POST /ats/jobs
1curl -X POST "http://localhost:8000/ats/jobs" \
2 -H "Content-Type: application/json" \
3 -d '{"title":"string","pipeline_id":"string","description":"string","department_mrn":"string","location":"string","workplace_type":null,"employment_type":null,"headcount":1,"hiring_manager_mrn":"string","recruiter_mrn":"string","hiring_team":[{"member_mrn":"string","role":null}],"approvals":[{"approver_mrn":"string","status":null,"comment":"string"}],"salary_min":1.5,"salary_max":1.5,"salary_currency":"string","salary_visible":null,"screening_questions":[{"text":"string","type":null,"key":"string","html":"string","options":["string"],"disqualify_on":["string"],"required":null}],"careers_visibility":null,"assessment_ref":"string"}'
1fetch("http://localhost:8000/ats/jobs", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "title": "string",
6 "pipeline_id": "string",
7 "description": "string",
8 "department_mrn": "string",
9 "location": "string",
10 "workplace_type": null,
11 "employment_type": null,
12 "headcount": 1,
13 "hiring_manager_mrn": "string",
14 "recruiter_mrn": "string",
15 "hiring_team": [
16 {
17 "member_mrn": "string",
18 "role": null
19 }
20 ],
21 "approvals": [
22 {
23 "approver_mrn": "string",
24 "status": null,
25 "comment": "string"
26 }
27 ],
28 "salary_min": 1.5,
29 "salary_max": 1.5,
30 "salary_currency": "string",
31 "salary_visible": null,
32 "screening_questions": [
33 {
34 "text": "string",
35 "type": null,
36 "key": "string",
37 "html": "string",
38 "options": [
39 "string"
40 ],
41 "disqualify_on": [
42 "string"
43 ],
44 "required": null
45 }
46 ],
47 "careers_visibility": null,
48 "assessment_ref": "string"
49}),
50})
51 .then((res) => res.json())
52 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/ats/jobs",
5 json={"title":"string","pipeline_id":"string","description":"string","department_mrn":"string","location":"string","workplace_type":null,"employment_type":null,"headcount":1,"hiring_manager_mrn":"string","recruiter_mrn":"string","hiring_team":[{"member_mrn":"string","role":null}],"approvals":[{"approver_mrn":"string","status":null,"comment":"string"}],"salary_min":1.5,"salary_max":1.5,"salary_currency":"string","salary_visible":null,"screening_questions":[{"text":"string","type":null,"key":"string","html":"string","options":["string"],"disqualify_on":["string"],"required":null}],"careers_visibility":null,"assessment_ref":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /ats/jobs/:job_id/approvals

Record an approval decision on a job

Handled by api_job_approval
Parameters
job_id string · path
required
Body · JobApprovalapplication/json
status
required
comment string · max length: 1000
propertyName anything
Responses
200Successful Response
POST /ats/jobs/example/approvals
1curl -X POST "http://localhost:8000/ats/jobs/example/approvals" \
2 -H "Content-Type: application/json" \
3 -d '{"status":null,"comment":"string"}'
1fetch("http://localhost:8000/ats/jobs/example/approvals", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "status": null,
6 "comment": "string"
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/ats/jobs/example/approvals",
5 json={"status":null,"comment":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /ats/pipelines

Create a pipeline

Handled by api_create_pipeline
Body · CreatePipelineapplication/json
name string · min length: 1 · max length: 100
required
description string · max length: 1000
is_default
propertyName anything
Responses
200Successful Response
POST /ats/pipelines
1curl -X POST "http://localhost:8000/ats/pipelines" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","description":"string","is_default":null}'
1fetch("http://localhost:8000/ats/pipelines", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "description": "string",
7 "is_default": null
8}),
9})
10 .then((res) => res.json())
11 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/ats/pipelines",
5 json={"name":"string","description":"string","is_default":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /ats/pipelines/:pipeline_id/stages

Add a stage to a pipeline

Handled by api_create_stage
Parameters
pipeline_id string · path
required
Body · CreateStageapplication/json
name string · min length: 1 · max length: 100
required
type
required
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
Responses
200Successful Response
POST /ats/pipelines/example/stages
1curl -X POST "http://localhost:8000/ats/pipelines/example/stages" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","type":null,"key":"string","position":1,"criteria":[{"label":"string","key":"string","weight":1,"competency_mrn":"string","description":"string"}],"questions":[{"text":"string","category":"string"}],"default_interviewers":["string"],"required_evaluations":1,"sla_days":1,"duration_minutes":1}'
1fetch("http://localhost:8000/ats/pipelines/example/stages", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "type": null,
7 "key": "string",
8 "position": 1,
9 "criteria": [
10 {
11 "label": "string",
12 "key": "string",
13 "weight": 1,
14 "competency_mrn": "string",
15 "description": "string"
16 }
17 ],
18 "questions": [
19 {
20 "text": "string",
21 "category": "string"
22 }
23 ],
24 "default_interviewers": [
25 "string"
26 ],
27 "required_evaluations": 1,
28 "sla_days": 1,
29 "duration_minutes": 1
30}),
31})
32 .then((res) => res.json())
33 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/ats/pipelines/example/stages",
5 json={"name":"string","type":null,"key":"string","position":1,"criteria":[{"label":"string","key":"string","weight":1,"competency_mrn":"string","description":"string"}],"questions":[{"text":"string","category":"string"}],"default_interviewers":["string"],"required_evaluations":1,"sla_days":1,"duration_minutes":1},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /ats/candidates

Create a candidate

Handled by api_create_candidate
Body · CreateCandidateapplication/json
name string · min length: 1 · max length: 200
required
email string · max length: 320 · email
required
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
Responses
200Successful Response
POST /ats/candidates
1curl -X POST "http://localhost:8000/ats/candidates" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","email":"user@example.com","phone":"string","location":"string","headline":"string","links":{"linkedin":"string","portfolio":"string","github":"string","other":"string"},"linkedin":"string","portfolio":"string","github":"string","tags":["string"],"source":null,"source_detail":"string","referrer_mrn":"string","owner_mrn":"string","resume":[{"key":"string","filename":"string","content_type":"string","size_bytes":1}]}'
1fetch("http://localhost:8000/ats/candidates", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "email": "user@example.com",
7 "phone": "string",
8 "location": "string",
9 "headline": "string",
10 "links": {
11 "linkedin": "string",
12 "portfolio": "string",
13 "github": "string",
14 "other": "string"
15 },
16 "linkedin": "string",
17 "portfolio": "string",
18 "github": "string",
19 "tags": [
20 "string"
21 ],
22 "source": null,
23 "source_detail": "string",
24 "referrer_mrn": "string",
25 "owner_mrn": "string",
26 "resume": [
27 {
28 "key": "string",
29 "filename": "string",
30 "content_type": "string",
31 "size_bytes": 1
32 }
33 ]
34}),
35})
36 .then((res) => res.json())
37 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/ats/candidates",
5 json={"name":"string","email":"user@example.com","phone":"string","location":"string","headline":"string","links":{"linkedin":"string","portfolio":"string","github":"string","other":"string"},"linkedin":"string","portfolio":"string","github":"string","tags":["string"],"source":null,"source_detail":"string","referrer_mrn":"string","owner_mrn":"string","resume":[{"key":"string","filename":"string","content_type":"string","size_bytes":1}]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /ats/candidates/:candidate_id/tags

Tag a candidate

Handled by api_add_tag
Parameters
candidate_id string · path
required
Body · AddTagapplication/json
tag string · min length: 1 · max length: 50
required
propertyName anything
Responses
200Successful Response
POST /ats/candidates/example/tags
1curl -X POST "http://localhost:8000/ats/candidates/example/tags" \
2 -H "Content-Type: application/json" \
3 -d '{"tag":"string"}'
1fetch("http://localhost:8000/ats/candidates/example/tags", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "tag": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/ats/candidates/example/tags",
5 json={"tag":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /ats/candidates/:candidate_id/activities

Add a note to a candidate's timeline

Handled by api_create_note
Parameters
candidate_id string · path
required
Body · CreateNoteapplication/json
content string · min length: 1 · max length: 20000
required
application_id string · max length: 100
propertyName anything
Responses
200Successful Response
POST /ats/candidates/example/activities
1curl -X POST "http://localhost:8000/ats/candidates/example/activities" \
2 -H "Content-Type: application/json" \
3 -d '{"content":"string","application_id":"string"}'
1fetch("http://localhost:8000/ats/candidates/example/activities", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "content": "string",
6 "application_id": "string"
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/ats/candidates/example/activities",
5 json={"content":"string","application_id":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /ats/candidates/:candidate_id/messages

Email a candidate from the careers mailbox

Handled by api_send_candidate_message
Parameters
candidate_id string · path
required
Body · SendCandidateMessageapplication/json
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
Responses
200Successful Response
POST /ats/candidates/example/messages
1curl -X POST "http://localhost:8000/ats/candidates/example/messages" \
2 -H "Content-Type: application/json" \
3 -d '{"template_id":"string","subject":"string","body_html":"string","application_id":"string"}'
1fetch("http://localhost:8000/ats/candidates/example/messages", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "template_id": "string",
6 "subject": "string",
7 "body_html": "string",
8 "application_id": "string"
9}),
10})
11 .then((res) => res.json())
12 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/ats/candidates/example/messages",
5 json={"template_id":"string","subject":"string","body_html":"string","application_id":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /ats/applications

Put a candidate against a job

Handled by api_create_application
Body · CreateApplicationapplication/json
candidate_id string · min length: 1 · max length: 100
required
job_id string · min length: 1 · max length: 100
required
stage_id string · max length: 100
source
propertyName anything
Responses
200Successful Response
POST /ats/applications
1curl -X POST "http://localhost:8000/ats/applications" \
2 -H "Content-Type: application/json" \
3 -d '{"candidate_id":"string","job_id":"string","stage_id":"string","source":null}'
1fetch("http://localhost:8000/ats/applications", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "candidate_id": "string",
6 "job_id": "string",
7 "stage_id": "string",
8 "source": null
9}),
10})
11 .then((res) => res.json())
12 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/ats/applications",
5 json={"candidate_id":"string","job_id":"string","stage_id":"string","source":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /ats/applications/:application_id/interviews

Request or schedule an interview

Handled by api_create_interview
Parameters
application_id string · path
required
Body · CreateInterviewapplication/json
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
Responses
200Successful Response
POST /ats/applications/example/interviews
1curl -X POST "http://localhost:8000/ats/applications/example/interviews" \
2 -H "Content-Type: application/json" \
3 -d '{"stage_id":"string","title":"string","panel":[{"member_mrn":"string","role":null}],"scheduled_at":"string","duration_minutes":1,"location":"string","instructions":"string"}'
1fetch("http://localhost:8000/ats/applications/example/interviews", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "stage_id": "string",
6 "title": "string",
7 "panel": [
8 {
9 "member_mrn": "string",
10 "role": null
11 }
12 ],
13 "scheduled_at": "string",
14 "duration_minutes": 1,
15 "location": "string",
16 "instructions": "string"
17}),
18})
19 .then((res) => res.json())
20 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/ats/applications/example/interviews",
5 json={"stage_id":"string","title":"string","panel":[{"member_mrn":"string","role":null}],"scheduled_at":"string","duration_minutes":1,"location":"string","instructions":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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.

Handled by api_self_schedule_interview
Parameters
interview_id string · path
required
Body · SelfScheduleInterviewapplication/json
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
Responses
200Successful Response
POST /ats/interviews/example/self-schedule
1curl -X POST "http://localhost:8000/ats/interviews/example/self-schedule" \
2 -H "Content-Type: application/json" \
3 -d '{"slots":[{"start":"string","end":"string"}],"slot_1":"string","slot_2":"string","slot_3":"string","slot_4":"string","slot_5":"string","duration_minutes":1,"expires_at":"string","location":"string","instructions":"string"}'
1fetch("http://localhost:8000/ats/interviews/example/self-schedule", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "slots": [
6 {
7 "start": "string",
8 "end": "string"
9 }
10 ],
11 "slot_1": "string",
12 "slot_2": "string",
13 "slot_3": "string",
14 "slot_4": "string",
15 "slot_5": "string",
16 "duration_minutes": 1,
17 "expires_at": "string",
18 "location": "string",
19 "instructions": "string"
20}),
21})
22 .then((res) => res.json())
23 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/ats/interviews/example/self-schedule",
5 json={"slots":[{"start":"string","end":"string"}],"slot_1":"string","slot_2":"string","slot_3":"string","slot_4":"string","slot_5":"string","duration_minutes":1,"expires_at":"string","location":"string","instructions":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /ats/applications/:application_id/evaluations

Ask a member for a scorecard

Handled by api_assign_evaluation
Parameters
application_id string · path
required
Body · AssignEvaluationapplication/json
evaluator_mrn string · min length: 1 · max length: 200
required
stage_id string · max length: 100
interview_id string · max length: 100
is_shadow
propertyName anything
Responses
200Successful Response
POST /ats/applications/example/evaluations
1curl -X POST "http://localhost:8000/ats/applications/example/evaluations" \
2 -H "Content-Type: application/json" \
3 -d '{"evaluator_mrn":"string","stage_id":"string","interview_id":"string","is_shadow":null}'
1fetch("http://localhost:8000/ats/applications/example/evaluations", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "evaluator_mrn": "string",
6 "stage_id": "string",
7 "interview_id": "string",
8 "is_shadow": null
9}),
10})
11 .then((res) => res.json())
12 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/ats/applications/example/evaluations",
5 json={"evaluator_mrn":"string","stage_id":"string","interview_id":"string","is_shadow":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /ats/applications/:application_id/offers

Draft an offer

Handled by api_create_offer
Parameters
application_id string · path
required
Body · CreateOfferapplication/json
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
Responses
200Successful Response
POST /ats/applications/example/offers
1curl -X POST "http://localhost:8000/ats/applications/example/offers" \
2 -H "Content-Type: application/json" \
3 -d '{"package":{"base":1.5,"currency":"string","period":null,"bonus":1.5,"equity":"string","benefits":["string"],"notes":"string"},"base":1.5,"currency":"string","period":null,"bonus":1.5,"equity":"string","benefits":["string"],"notes":"string","start_date":"string","expires_at":"string","template_id":"string","approvals":[{"approver_mrn":"string","status":null,"comment":"string"}]}'
1fetch("http://localhost:8000/ats/applications/example/offers", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "package": {
6 "base": 1.5,
7 "currency": "string",
8 "period": null,
9 "bonus": 1.5,
10 "equity": "string",
11 "benefits": [
12 "string"
13 ],
14 "notes": "string"
15 },
16 "base": 1.5,
17 "currency": "string",
18 "period": null,
19 "bonus": 1.5,
20 "equity": "string",
21 "benefits": [
22 "string"
23 ],
24 "notes": "string",
25 "start_date": "string",
26 "expires_at": "string",
27 "template_id": "string",
28 "approvals": [
29 {
30 "approver_mrn": "string",
31 "status": null,
32 "comment": "string"
33 }
34 ]
35}),
36})
37 .then((res) => res.json())
38 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/ats/applications/example/offers",
5 json={"package":{"base":1.5,"currency":"string","period":null,"bonus":1.5,"equity":"string","benefits":["string"],"notes":"string"},"base":1.5,"currency":"string","period":null,"bonus":1.5,"equity":"string","benefits":["string"],"notes":"string","start_date":"string","expires_at":"string","template_id":"string","approvals":[{"approver_mrn":"string","status":null,"comment":"string"}]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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.

Handled by api_offer_approval
Parameters
offer_id string · path
required
Body · OfferApprovalapplication/json
status
required
comment string · max length: 1000
propertyName anything
Responses
200Successful Response
POST /ats/offers/example/approvals
1curl -X POST "http://localhost:8000/ats/offers/example/approvals" \
2 -H "Content-Type: application/json" \
3 -d '{"status":null,"comment":"string"}'
1fetch("http://localhost:8000/ats/offers/example/approvals", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "status": null,
6 "comment": "string"
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/ats/offers/example/approvals",
5 json={"status":null,"comment":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /ats/templates

Create a template

Handled by api_create_template
Body · CreateTemplateapplication/json
kind
required
name string · min length: 1 · max length: 100
required
subject string · max length: 300
body string · max length: 50000
config object
sign_template_id string · max length: 100
is_default
propertyName anything
Responses
200Successful Response
POST /ats/templates
1curl -X POST "http://localhost:8000/ats/templates" \
2 -H "Content-Type: application/json" \
3 -d '{"kind":null,"name":"string","subject":"string","body":"string","config":{"sign_template_id":"string"},"sign_template_id":"string","is_default":null}'
1fetch("http://localhost:8000/ats/templates", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "kind": null,
6 "name": "string",
7 "subject": "string",
8 "body": "string",
9 "config": {
10 "sign_template_id": "string"
11 },
12 "sign_template_id": "string",
13 "is_default": null
14}),
15})
16 .then((res) => res.json())
17 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/ats/templates",
5 json={"kind":null,"name":"string","subject":"string","body":"string","config":{"sign_template_id":"string"},"sign_template_id":"string","is_default":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /ats/settings/embeds

Create a careers embed

POST /ats/settings/embeds: mint a named embed for one website.

Handled by api_create_embed
Body · CreateCareersEmbedapplication/json
name string · min length: 1 · max length: 120
required
enabled
allowed_origins array
filters object
layout
show_search
heading string · max length: 120
propertyName anything
Responses
200Successful Response
POST /ats/settings/embeds
1curl -X POST "http://localhost:8000/ats/settings/embeds" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","enabled":null,"allowed_origins":["string"],"filters":{"workplace_type":[null],"employment_type":[null],"location_contains":"string","tags":["string"]},"layout":null,"show_search":null,"heading":"string"}'
1fetch("http://localhost:8000/ats/settings/embeds", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "enabled": null,
7 "allowed_origins": [
8 "string"
9 ],
10 "filters": {
11 "workplace_type": [
12 null
13 ],
14 "employment_type": [
15 null
16 ],
17 "location_contains": "string",
18 "tags": [
19 "string"
20 ]
21 },
22 "layout": null,
23 "show_search": null,
24 "heading": "string"
25}),
26})
27 .then((res) => res.json())
28 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/ats/settings/embeds",
5 json={"name":"string","enabled":null,"allowed_origins":["string"],"filters":{"workplace_type":[null],"employment_type":[null],"location_contains":"string","tags":["string"]},"layout":null,"show_search":null,"heading":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /ats/jobs/:job_id

Update a job

Handled by api_update_job
Parameters
job_id string · path
required
Body · UpdateJobapplication/json
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
Responses
200Successful Response
PUT /ats/jobs/example
1curl -X PUT "http://localhost:8000/ats/jobs/example" \
2 -H "Content-Type: application/json" \
3 -d '{"title":"string","pipeline_id":"string","description":"string","department_mrn":"string","location":"string","workplace_type":null,"employment_type":null,"headcount":1,"hiring_manager_mrn":"string","recruiter_mrn":"string","hiring_team":[{"member_mrn":"string","role":null}],"approvals":[{"approver_mrn":"string","status":null,"comment":"string"}],"salary_min":1.5,"salary_max":1.5,"salary_currency":"string","salary_visible":null,"screening_questions":[{"text":"string","type":null,"key":"string","html":"string","options":["string"],"disqualify_on":["string"],"required":null}],"careers_visibility":null,"assessment_ref":"string"}'
1fetch("http://localhost:8000/ats/jobs/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "title": "string",
6 "pipeline_id": "string",
7 "description": "string",
8 "department_mrn": "string",
9 "location": "string",
10 "workplace_type": null,
11 "employment_type": null,
12 "headcount": 1,
13 "hiring_manager_mrn": "string",
14 "recruiter_mrn": "string",
15 "hiring_team": [
16 {
17 "member_mrn": "string",
18 "role": null
19 }
20 ],
21 "approvals": [
22 {
23 "approver_mrn": "string",
24 "status": null,
25 "comment": "string"
26 }
27 ],
28 "salary_min": 1.5,
29 "salary_max": 1.5,
30 "salary_currency": "string",
31 "salary_visible": null,
32 "screening_questions": [
33 {
34 "text": "string",
35 "type": null,
36 "key": "string",
37 "html": "string",
38 "options": [
39 "string"
40 ],
41 "disqualify_on": [
42 "string"
43 ],
44 "required": null
45 }
46 ],
47 "careers_visibility": null,
48 "assessment_ref": "string"
49}),
50})
51 .then((res) => res.json())
52 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/ats/jobs/example",
5 json={"title":"string","pipeline_id":"string","description":"string","department_mrn":"string","location":"string","workplace_type":null,"employment_type":null,"headcount":1,"hiring_manager_mrn":"string","recruiter_mrn":"string","hiring_team":[{"member_mrn":"string","role":null}],"approvals":[{"approver_mrn":"string","status":null,"comment":"string"}],"salary_min":1.5,"salary_max":1.5,"salary_currency":"string","salary_visible":null,"screening_questions":[{"text":"string","type":null,"key":"string","html":"string","options":["string"],"disqualify_on":["string"],"required":null}],"careers_visibility":null,"assessment_ref":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /ats/pipelines/:pipeline_id

Update a pipeline

Handled by api_update_pipeline
Parameters
pipeline_id string · path
required
Body · UpdatePipelineapplication/json
name string · min length: 1 · max length: 100
description string · max length: 1000
is_default
status
propertyName anything
Responses
200Successful Response
PUT /ats/pipelines/example
1curl -X PUT "http://localhost:8000/ats/pipelines/example" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","description":"string","is_default":null,"status":null}'
1fetch("http://localhost:8000/ats/pipelines/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "description": "string",
7 "is_default": null,
8 "status": null
9}),
10})
11 .then((res) => res.json())
12 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/ats/pipelines/example",
5 json={"name":"string","description":"string","is_default":null,"status":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /ats/stages/:stage_id

Update a stage

Handled by api_update_stage
Parameters
stage_id string · path
required
Body · UpdateStageapplication/json
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
Responses
200Successful Response
PUT /ats/stages/example
1curl -X PUT "http://localhost:8000/ats/stages/example" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","type":null,"key":"string","criteria":[{"label":"string","key":"string","weight":1,"competency_mrn":"string","description":"string"}],"questions":[{"text":"string","category":"string"}],"default_interviewers":["string"],"required_evaluations":1,"sla_days":1,"duration_minutes":1}'
1fetch("http://localhost:8000/ats/stages/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "type": null,
7 "key": "string",
8 "criteria": [
9 {
10 "label": "string",
11 "key": "string",
12 "weight": 1,
13 "competency_mrn": "string",
14 "description": "string"
15 }
16 ],
17 "questions": [
18 {
19 "text": "string",
20 "category": "string"
21 }
22 ],
23 "default_interviewers": [
24 "string"
25 ],
26 "required_evaluations": 1,
27 "sla_days": 1,
28 "duration_minutes": 1
29}),
30})
31 .then((res) => res.json())
32 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/ats/stages/example",
5 json={"name":"string","type":null,"key":"string","criteria":[{"label":"string","key":"string","weight":1,"competency_mrn":"string","description":"string"}],"questions":[{"text":"string","category":"string"}],"default_interviewers":["string"],"required_evaluations":1,"sla_days":1,"duration_minutes":1},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /ats/candidates/:candidate_id

Update a candidate

Handled by api_update_candidate
Parameters
candidate_id string · path
required
Body · UpdateCandidateapplication/json
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
Responses
200Successful Response
PUT /ats/candidates/example
1curl -X PUT "http://localhost:8000/ats/candidates/example" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","email":"user@example.com","phone":"string","location":"string","headline":"string","links":{"linkedin":"string","portfolio":"string","github":"string","other":"string"},"linkedin":"string","portfolio":"string","github":"string","tags":["string"],"source":null,"source_detail":"string","referrer_mrn":"string","owner_mrn":"string","is_archived":null,"resume":[{"key":"string","filename":"string","content_type":"string","size_bytes":1}]}'
1fetch("http://localhost:8000/ats/candidates/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "email": "user@example.com",
7 "phone": "string",
8 "location": "string",
9 "headline": "string",
10 "links": {
11 "linkedin": "string",
12 "portfolio": "string",
13 "github": "string",
14 "other": "string"
15 },
16 "linkedin": "string",
17 "portfolio": "string",
18 "github": "string",
19 "tags": [
20 "string"
21 ],
22 "source": null,
23 "source_detail": "string",
24 "referrer_mrn": "string",
25 "owner_mrn": "string",
26 "is_archived": null,
27 "resume": [
28 {
29 "key": "string",
30 "filename": "string",
31 "content_type": "string",
32 "size_bytes": 1
33 }
34 ]
35}),
36})
37 .then((res) => res.json())
38 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/ats/candidates/example",
5 json={"name":"string","email":"user@example.com","phone":"string","location":"string","headline":"string","links":{"linkedin":"string","portfolio":"string","github":"string","other":"string"},"linkedin":"string","portfolio":"string","github":"string","tags":["string"],"source":null,"source_detail":"string","referrer_mrn":"string","owner_mrn":"string","is_archived":null,"resume":[{"key":"string","filename":"string","content_type":"string","size_bytes":1}]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /ats/interviews/:interview_id

Update an interview and its panel

Handled by api_update_interview
Parameters
interview_id string · path
required
Body · UpdateInterviewapplication/json
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
Responses
200Successful Response
PUT /ats/interviews/example
1curl -X PUT "http://localhost:8000/ats/interviews/example" \
2 -H "Content-Type: application/json" \
3 -d '{"title":"string","stage_id":"string","panel":[{"member_mrn":"string","role":null}],"duration_minutes":1,"location":"string","instructions":"string","status":null}'
1fetch("http://localhost:8000/ats/interviews/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "title": "string",
6 "stage_id": "string",
7 "panel": [
8 {
9 "member_mrn": "string",
10 "role": null
11 }
12 ],
13 "duration_minutes": 1,
14 "location": "string",
15 "instructions": "string",
16 "status": null
17}),
18})
19 .then((res) => res.json())
20 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/ats/interviews/example",
5 json={"title":"string","stage_id":"string","panel":[{"member_mrn":"string","role":null}],"duration_minutes":1,"location":"string","instructions":"string","status":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /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.

Handled by api_submit_evaluation
Parameters
evaluation_id string · path
required
Body · SubmitEvaluationapplication/json
rating integer · min: 1 · max: 5
required
recommendation
required
scores
question_responses array
strengths string · max length: 2000
concerns string · max length: 2000
notes string · max length: 5000
propertyName anything
Responses
200Successful Response
PUT /ats/evaluations/example
1curl -X PUT "http://localhost:8000/ats/evaluations/example" \
2 -H "Content-Type: application/json" \
3 -d '{"rating":1,"recommendation":null,"scores":null,"question_responses":[{"question":"string","answer":"string"}],"strengths":"string","concerns":"string","notes":"string"}'
1fetch("http://localhost:8000/ats/evaluations/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "rating": 1,
6 "recommendation": null,
7 "scores": null,
8 "question_responses": [
9 {
10 "question": "string",
11 "answer": "string"
12 }
13 ],
14 "strengths": "string",
15 "concerns": "string",
16 "notes": "string"
17}),
18})
19 .then((res) => res.json())
20 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/ats/evaluations/example",
5 json={"rating":1,"recommendation":null,"scores":null,"question_responses":[{"question":"string","answer":"string"}],"strengths":"string","concerns":"string","notes":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /ats/offers/:offer_id

Update a draft offer

Handled by api_update_offer
Parameters
offer_id string · path
required
Body · UpdateOfferapplication/json
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
Responses
200Successful Response
PUT /ats/offers/example
1curl -X PUT "http://localhost:8000/ats/offers/example" \
2 -H "Content-Type: application/json" \
3 -d '{"package":{"base":1.5,"currency":"string","period":null,"bonus":1.5,"equity":"string","benefits":["string"],"notes":"string"},"base":1.5,"currency":"string","period":null,"bonus":1.5,"equity":"string","benefits":["string"],"notes":"string","start_date":"string","expires_at":"string","template_id":"string","approvals":[{"approver_mrn":"string","status":null,"comment":"string"}]}'
1fetch("http://localhost:8000/ats/offers/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "package": {
6 "base": 1.5,
7 "currency": "string",
8 "period": null,
9 "bonus": 1.5,
10 "equity": "string",
11 "benefits": [
12 "string"
13 ],
14 "notes": "string"
15 },
16 "base": 1.5,
17 "currency": "string",
18 "period": null,
19 "bonus": 1.5,
20 "equity": "string",
21 "benefits": [
22 "string"
23 ],
24 "notes": "string",
25 "start_date": "string",
26 "expires_at": "string",
27 "template_id": "string",
28 "approvals": [
29 {
30 "approver_mrn": "string",
31 "status": null,
32 "comment": "string"
33 }
34 ]
35}),
36})
37 .then((res) => res.json())
38 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/ats/offers/example",
5 json={"package":{"base":1.5,"currency":"string","period":null,"bonus":1.5,"equity":"string","benefits":["string"],"notes":"string"},"base":1.5,"currency":"string","period":null,"bonus":1.5,"equity":"string","benefits":["string"],"notes":"string","start_date":"string","expires_at":"string","template_id":"string","approvals":[{"approver_mrn":"string","status":null,"comment":"string"}]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /ats/templates/:template_id

Update a template

Handled by api_update_template
Parameters
template_id string · path
required
Body · UpdateTemplateapplication/json
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
Responses
200Successful Response
PUT /ats/templates/example
1curl -X PUT "http://localhost:8000/ats/templates/example" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","subject":"string","body":"string","config":{"sign_template_id":"string"},"sign_template_id":"string","is_default":null,"status":null}'
1fetch("http://localhost:8000/ats/templates/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "subject": "string",
7 "body": "string",
8 "config": {
9 "sign_template_id": "string"
10 },
11 "sign_template_id": "string",
12 "is_default": null,
13 "status": null
14}),
15})
16 .then((res) => res.json())
17 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/ats/templates/example",
5 json={"name":"string","subject":"string","body":"string","config":{"sign_template_id":"string"},"sign_template_id":"string","is_default":null,"status":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /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.

Handled by api_update_embed
Parameters
embed_id string · path
required
Body · UpdateCareersEmbedapplication/json
name string · min length: 1 · max length: 120
enabled
allowed_origins array
filters object
layout
show_search
heading string · max length: 120
propertyName anything
Responses
200Successful Response
PUT /ats/settings/embeds/example
1curl -X PUT "http://localhost:8000/ats/settings/embeds/example" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","enabled":null,"allowed_origins":["string"],"filters":{"workplace_type":[null],"employment_type":[null],"location_contains":"string","tags":["string"]},"layout":null,"show_search":null,"heading":"string"}'
1fetch("http://localhost:8000/ats/settings/embeds/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "enabled": null,
7 "allowed_origins": [
8 "string"
9 ],
10 "filters": {
11 "workplace_type": [
12 null
13 ],
14 "employment_type": [
15 null
16 ],
17 "location_contains": "string",
18 "tags": [
19 "string"
20 ]
21 },
22 "layout": null,
23 "show_search": null,
24 "heading": "string"
25}),
26})
27 .then((res) => res.json())
28 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/ats/settings/embeds/example",
5 json={"name":"string","enabled":null,"allowed_origins":["string"],"filters":{"workplace_type":[null],"employment_type":[null],"location_contains":"string","tags":["string"]},"layout":null,"show_search":null,"heading":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /me/notification-preferences

Patch notification prefs

Handled by api_patch_notification_prefs
Body · UpdateNotificationPrefsapplication/json
channel
required
patch object
required
propertyName anything
Responses
200Successful Response
PATCH /me/notification-preferences
1curl -X PATCH "http://localhost:8000/me/notification-preferences" \
2 -H "Content-Type: application/json" \
3 -d '{"channel":null,"patch":{"enabled":null,"toast":null,"push":null,"sound":"string"}}'
1fetch("http://localhost:8000/me/notification-preferences", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "channel": null,
6 "patch": {
7 "enabled": null,
8 "toast": null,
9 "push": null,
10 "sound": "string"
11 }
12}),
13})
14 .then((res) => res.json())
15 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/me/notification-preferences",
5 json={"channel":null,"patch":{"enabled":null,"toast":null,"push":null,"sound":"string"}},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /push-subscriptions

Turn on notifications for this browser

POST /push-subscriptions: this browser may now show notifications for the signed-in person.

Handled by api_create_subscription
Body · CreatePushSubscriptionapplication/json
endpoint string · min length: 10 · max length: 2000
required
keys object
required
propertyName anything
Responses
200Successful Response
POST /push-subscriptions
1curl -X POST "http://localhost:8000/push-subscriptions" \
2 -H "Content-Type: application/json" \
3 -d '{"endpoint":"string","keys":{"p256dh":"string","auth":"string"}}'
1fetch("http://localhost:8000/push-subscriptions", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "endpoint": "string",
6 "keys": {
7 "p256dh": "string",
8 "auth": "string"
9 }
10}),
11})
12 .then((res) => res.json())
13 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/push-subscriptions",
5 json={"endpoint":"string","keys":{"p256dh":"string","auth":"string"}},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /push-devices

Turn on notifications for this phone

POST /push-devices: this phone may now show notifications for the signed-in person.

Handled by api_create_device
Body · CreatePushDeviceapplication/json
token string · min length: 20 · max length: 4096
required
platform
required
propertyName anything
Responses
200Successful Response
POST /push-devices
1curl -X POST "http://localhost:8000/push-devices" \
2 -H "Content-Type: application/json" \
3 -d '{"token":"string","platform":null}'
1fetch("http://localhost:8000/push-devices", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "token": "string",
6 "platform": null
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/push-devices",
5 json={"token":"string","platform":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /finance/accounts

Create an account

Handled by api_create_account
Body · CreateAccountapplication/json
code string · min length: 1 · max length: 20
required
name string · min length: 1 · max length: 200
required
type
required
parent_id string
description string · max length: 1000
normal_balance
is_contra
is_bank
propertyName anything
Responses
200Successful Response
POST /finance/accounts
1curl -X POST "http://localhost:8000/finance/accounts" \
2 -H "Content-Type: application/json" \
3 -d '{"code":"string","name":"string","type":null,"parent_id":"string","description":"string","normal_balance":null,"is_contra":null,"is_bank":null}'
1fetch("http://localhost:8000/finance/accounts", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "code": "string",
6 "name": "string",
7 "type": null,
8 "parent_id": "string",
9 "description": "string",
10 "normal_balance": null,
11 "is_contra": null,
12 "is_bank": null
13}),
14})
15 .then((res) => res.json())
16 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/finance/accounts",
5 json={"code":"string","name":"string","type":null,"parent_id":"string","description":"string","normal_balance":null,"is_contra":null,"is_bank":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /finance/accounts/:account_id

Update an account

Handled by api_update_account
Parameters
account_id string · path
required
Body · UpdateAccountapplication/json
display_name string · max length: 200
show_in_unified
propertyName anything
Responses
200Successful Response
PUT /finance/accounts/example
1curl -X PUT "http://localhost:8000/finance/accounts/example" \
2 -H "Content-Type: application/json" \
3 -d '{"display_name":"string","show_in_unified":null}'
1fetch("http://localhost:8000/finance/accounts/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "display_name": "string",
6 "show_in_unified": null
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/finance/accounts/example",
5 json={"display_name":"string","show_in_unified":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
GET /activity undocumented

/activity

Handled by api_list_activity
Responses
200Successful Response
GET /activity
1curl "http://localhost:8000/activity"
1fetch("http://localhost:8000/activity")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/activity")
4print(response.json())
200 Example Response
No Body
GET /admin/file-members/:member_mrn/folders undocumented

/admin/file-members/:member_mrn/folders

Handled by api_admin_list_member_folders
Parameters
member_mrn string · path
required
Responses
200Successful Response
GET /admin/file-members/example/folders
1curl "http://localhost:8000/admin/file-members/example/folders"
1fetch("http://localhost:8000/admin/file-members/example/folders")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/admin/file-members/example/folders")
4print(response.json())
200 Example Response
No Body
GET /admin/file-members/:member_mrn/files undocumented

/admin/file-members/:member_mrn/files

Handled by api_admin_list_member_files
Parameters
member_mrn string · path
required
Responses
200Successful Response
GET /admin/file-members/example/files
1curl "http://localhost:8000/admin/file-members/example/files"
1fetch("http://localhost:8000/admin/file-members/example/files")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/admin/file-members/example/files")
4print(response.json())
200 Example Response
No Body
GET /admin/file-stats undocumented

/admin/file-stats

GET /admin/file-stats — workspace storage overview for the admin view.

Handled by api_admin_file_stats
Responses
200Successful Response
GET /admin/file-stats
1curl "http://localhost:8000/admin/file-stats"
1fetch("http://localhost:8000/admin/file-stats")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/admin/file-stats")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_admin_activity_export
Responses
200Successful Response
GET /admin/activity-exports
1curl "http://localhost:8000/admin/activity-exports"
1fetch("http://localhost:8000/admin/activity-exports")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/admin/activity-exports")
4print(response.json())
200 Example Response
No Body
POST /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.

Handled by api_admin_transfer_files
Body · TransferFilesapplication/json
from_mrn string · min length: 1
required
to_mrn string · min length: 1
required
propertyName anything
Responses
200Successful Response
POST /admin/file-transfers
1curl -X POST "http://localhost:8000/admin/file-transfers" \
2 -H "Content-Type: application/json" \
3 -d '{"from_mrn":"string","to_mrn":"string"}'
1fetch("http://localhost:8000/admin/file-transfers", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "from_mrn": "string",
6 "to_mrn": "string"
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/admin/file-transfers",
5 json={"from_mrn":"string","to_mrn":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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.

Handled by api_start_elevation
Body · StartElevationapplication/json
reason string · min length: 3 · max length: 500
required
code string · min length: 6 · max length: 6
totp string · min length: 6 · max length: 10
propertyName anything
Responses
200Successful Response
POST /elevations
1curl -X POST "http://localhost:8000/elevations" \
2 -H "Content-Type: application/json" \
3 -d '{"reason":"string","code":"string","totp":"string"}'
1fetch("http://localhost:8000/elevations", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "reason": "string",
6 "code": "string",
7 "totp": "string"
8}),
9})
10 .then((res) => res.json())
11 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/elevations",
5 json={"reason":"string","code":"string","totp":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
GET /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.

Handled by api_list_admin_audit
Responses
200Successful Response
GET /admin-audit
1curl "http://localhost:8000/admin-audit"
1fetch("http://localhost:8000/admin-audit")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/admin-audit")
4print(response.json())
200 Example Response
No Body
DELETE /api-keys/:key_id undocumented

/api-keys/:key_id

DELETE /api-keys/:key_id: remove the key and its audit row.

Handled by api_delete_api_key
Parameters
key_id string · path
required
Responses
200Successful Response
DELETE /api-keys/example
1curl -X DELETE "http://localhost:8000/api-keys/example"
1fetch("http://localhost:8000/api-keys/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/api-keys/example")
4print(response.json())
200 Example Response
No Body
GET /api-keys undocumented

/api-keys

GET /api-keys: list the workspace's API keys (never the secrets).

Handled by api_list_api_keys
Responses
200Successful Response
GET /api-keys
1curl "http://localhost:8000/api-keys"
1fetch("http://localhost:8000/api-keys")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/api-keys")
4print(response.json())
200 Example Response
No Body
GET /applications/:slug/status undocumented

/applications/:slug/status

GET /accounts/apps/status/:slug — Check install status for a specific app.

Handled by api_app_status
Parameters
slug string · path
required
Responses
200Successful Response
GET /applications/example/status
1curl "http://localhost:8000/applications/example/status"
1fetch("http://localhost:8000/applications/example/status")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/applications/example/status")
4print(response.json())
200 Example Response
No Body
POST /applications/:slug/requests undocumented

/applications/:slug/requests

POST /applications/:slug/requests — Request app install (any authenticated member).

Handled by api_request_install
Parameters
slug string · path
required
Responses
200Successful Response
POST /applications/example/requests
1curl -X POST "http://localhost:8000/applications/example/requests"
1fetch("http://localhost:8000/applications/example/requests", { method: "POST" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.post("http://localhost:8000/applications/example/requests")
4print(response.json())
200 Example Response
No Body
GET /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".

Handled by api_app_access
Parameters
slug string · path
required
Responses
200Successful Response
GET /apps/example/access
1curl "http://localhost:8000/apps/example/access"
1fetch("http://localhost:8000/apps/example/access")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/apps/example/access")
4print(response.json())
200 Example Response
No Body
GET /apps/:slug/settings undocumented

/apps/:slug/settings

GET /apps/:slug/settings — the app's effective config document.

Handled by api_get_app_settings
Parameters
slug string · path
required
Responses
200Successful Response
GET /apps/example/settings
1curl "http://localhost:8000/apps/example/settings"
1fetch("http://localhost:8000/apps/example/settings")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/apps/example/settings")
4print(response.json())
200 Example Response
No Body
POST /applications/:slug/installations

Install app

POST /accounts/apps/install — Install an app (admin/owner only).

Handled by api_install_app
Parameters
slug string · path
required
Body · InstallAppapplication/json
access_policy
allowed_roles array
propertyName anything
Responses
200Successful Response
POST /applications/example/installations
1curl -X POST "http://localhost:8000/applications/example/installations" \
2 -H "Content-Type: application/json" \
3 -d '{"access_policy":null,"allowed_roles":["string"]}'
1fetch("http://localhost:8000/applications/example/installations", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "access_policy": null,
6 "allowed_roles": [
7 "string"
8 ]
9}),
10})
11 .then((res) => res.json())
12 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/applications/example/installations",
5 json={"access_policy":null,"allowed_roles":["string"]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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.

Handled by api_request_access
Parameters
slug string · path
required
Body · RequestAppAccessapplication/json
message string · max length: 280
propertyName anything
Responses
200Successful Response
POST /applications/example/access-requests
1curl -X POST "http://localhost:8000/applications/example/access-requests" \
2 -H "Content-Type: application/json" \
3 -d '{"message":"string"}'
1fetch("http://localhost:8000/applications/example/access-requests", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "message": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/applications/example/access-requests",
5 json={"message":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /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.

Handled by api_update_app_access
Parameters
slug string · path
required
Body · UpdateAppAccessapplication/json
access_policy
required
allowed_roles array
redlist array
propertyName anything
Responses
200Successful Response
PUT /applications/example/access
1curl -X PUT "http://localhost:8000/applications/example/access" \
2 -H "Content-Type: application/json" \
3 -d '{"access_policy":null,"allowed_roles":["string"],"redlist":["string"]}'
1fetch("http://localhost:8000/applications/example/access", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "access_policy": null,
6 "allowed_roles": [
7 "string"
8 ],
9 "redlist": [
10 "string"
11 ]
12}),
13})
14 .then((res) => res.json())
15 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/applications/example/access",
5 json={"access_policy":null,"allowed_roles":["string"],"redlist":["string"]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /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.

Handled by api_update_app_role_slice
Parameters
slug string · path
required
role_id string · path
required
Body · UpdateAppRoleSliceapplication/json
permissions array
required
propertyName anything
Responses
200Successful Response
PUT /apps/example/roles/example/permissions
1curl -X PUT "http://localhost:8000/apps/example/roles/example/permissions" \
2 -H "Content-Type: application/json" \
3 -d '{"permissions":["string"]}'
1fetch("http://localhost:8000/apps/example/roles/example/permissions", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "permissions": [
6 "string"
7 ]
8}),
9})
10 .then((res) => res.json())
11 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/apps/example/roles/example/permissions",
5 json={"permissions":["string"]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /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).

Handled by api_put_app_settings
Parameters
slug string · path
required
Responses
200Successful Response
PUT /apps/example/settings
1curl -X PUT "http://localhost:8000/apps/example/settings"
1fetch("http://localhost:8000/apps/example/settings", { method: "PUT" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.put("http://localhost:8000/apps/example/settings")
4print(response.json())
200 Example Response
No Body
DELETE /ats/jobs/:job_id undocumented

/ats/jobs/:job_id

Handled by api_delete_job
Parameters
job_id string · path
required
Responses
200Successful Response
DELETE /ats/jobs/example
1curl -X DELETE "http://localhost:8000/ats/jobs/example"
1fetch("http://localhost:8000/ats/jobs/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/ats/jobs/example")
4print(response.json())
200 Example Response
No Body
DELETE /ats/pipelines/:pipeline_id undocumented

/ats/pipelines/:pipeline_id

Handled by api_delete_pipeline
Parameters
pipeline_id string · path
required
Responses
200Successful Response
DELETE /ats/pipelines/example
1curl -X DELETE "http://localhost:8000/ats/pipelines/example"
1fetch("http://localhost:8000/ats/pipelines/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/ats/pipelines/example")
4print(response.json())
200 Example Response
No Body
DELETE /ats/stages/:stage_id undocumented

/ats/stages/:stage_id

Handled by api_delete_stage
Parameters
stage_id string · path
required
Responses
200Successful Response
DELETE /ats/stages/example
1curl -X DELETE "http://localhost:8000/ats/stages/example"
1fetch("http://localhost:8000/ats/stages/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/ats/stages/example")
4print(response.json())
200 Example Response
No Body
DELETE /ats/candidates/:candidate_id/tags/:tag undocumented

/ats/candidates/:candidate_id/tags/:tag

Handled by api_remove_tag
Parameters
candidate_id string · path
required
tag string · path
required
Responses
200Successful Response
DELETE /ats/candidates/example/tags/example
1curl -X DELETE "http://localhost:8000/ats/candidates/example/tags/example"
1fetch("http://localhost:8000/ats/candidates/example/tags/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/ats/candidates/example/tags/example")
4print(response.json())
200 Example Response
No Body
DELETE /ats/applications/:application_id undocumented

/ats/applications/:application_id

Handled by api_delete_application
Parameters
application_id string · path
required
Responses
200Successful Response
DELETE /ats/applications/example
1curl -X DELETE "http://localhost:8000/ats/applications/example"
1fetch("http://localhost:8000/ats/applications/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/ats/applications/example")
4print(response.json())
200 Example Response
No Body
DELETE /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.

Handled by api_cancel_interview
Parameters
interview_id string · path
required
Responses
200Successful Response
DELETE /ats/interviews/example
1curl -X DELETE "http://localhost:8000/ats/interviews/example"
1fetch("http://localhost:8000/ats/interviews/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/ats/interviews/example")
4print(response.json())
200 Example Response
No Body
DELETE /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.

Handled by api_cancel_evaluation
Parameters
evaluation_id string · path
required
Responses
200Successful Response
DELETE /ats/evaluations/example
1curl -X DELETE "http://localhost:8000/ats/evaluations/example"
1fetch("http://localhost:8000/ats/evaluations/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/ats/evaluations/example")
4print(response.json())
200 Example Response
No Body
DELETE /ats/templates/:template_id undocumented

/ats/templates/:template_id

Handled by api_delete_template
Parameters
template_id string · path
required
Responses
200Successful Response
DELETE /ats/templates/example
1curl -X DELETE "http://localhost:8000/ats/templates/example"
1fetch("http://localhost:8000/ats/templates/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/ats/templates/example")
4print(response.json())
200 Example Response
No Body
DELETE /ats/settings/embeds/:embed_id undocumented

/ats/settings/embeds/:embed_id

DELETE /ats/settings/embeds/:embed_id: retire a snippet for good.

Handled by api_delete_embed
Parameters
embed_id string · path
required
Responses
200Successful Response
DELETE /ats/settings/embeds/example
1curl -X DELETE "http://localhost:8000/ats/settings/embeds/example"
1fetch("http://localhost:8000/ats/settings/embeds/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/ats/settings/embeds/example")
4print(response.json())
200 Example Response
No Body
GET /ats/jobs undocumented

/ats/jobs

Handled by api_list_jobs
Responses
200Successful Response
GET /ats/jobs
1curl "http://localhost:8000/ats/jobs"
1fetch("http://localhost:8000/ats/jobs")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/ats/jobs")
4print(response.json())
200 Example Response
No Body
GET /ats/jobs/:job_id undocumented

/ats/jobs/:job_id

Handled by api_get_job
Parameters
job_id string · path
required
Responses
200Successful Response
GET /ats/jobs/example
1curl "http://localhost:8000/ats/jobs/example"
1fetch("http://localhost:8000/ats/jobs/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/ats/jobs/example")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_job_matches
Parameters
job_id string · path
required
Responses
200Successful Response
GET /ats/jobs/example/matches
1curl "http://localhost:8000/ats/jobs/example/matches"
1fetch("http://localhost:8000/ats/jobs/example/matches")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/ats/jobs/example/matches")
4print(response.json())
200 Example Response
No Body
GET /ats/pipelines undocumented

/ats/pipelines

Handled by api_list_pipelines
Responses
200Successful Response
GET /ats/pipelines
1curl "http://localhost:8000/ats/pipelines"
1fetch("http://localhost:8000/ats/pipelines")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/ats/pipelines")
4print(response.json())
200 Example Response
No Body
GET /ats/pipelines/:pipeline_id undocumented

/ats/pipelines/:pipeline_id

Handled by api_get_pipeline
Parameters
pipeline_id string · path
required
Responses
200Successful Response
GET /ats/pipelines/example
1curl "http://localhost:8000/ats/pipelines/example"
1fetch("http://localhost:8000/ats/pipelines/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/ats/pipelines/example")
4print(response.json())
200 Example Response
No Body
GET /ats/pipelines/:pipeline_id/stages undocumented

/ats/pipelines/:pipeline_id/stages

Handled by api_list_stages
Parameters
pipeline_id string · path
required
Responses
200Successful Response
GET /ats/pipelines/example/stages
1curl "http://localhost:8000/ats/pipelines/example/stages"
1fetch("http://localhost:8000/ats/pipelines/example/stages")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/ats/pipelines/example/stages")
4print(response.json())
200 Example Response
No Body
GET /ats/candidates undocumented

/ats/candidates

Handled by api_list_candidates
Responses
200Successful Response
GET /ats/candidates
1curl "http://localhost:8000/ats/candidates"
1fetch("http://localhost:8000/ats/candidates")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/ats/candidates")
4print(response.json())
200 Example Response
No Body
GET /ats/candidates/:candidate_id undocumented

/ats/candidates/:candidate_id

Handled by api_get_candidate
Parameters
candidate_id string · path
required
Responses
200Successful Response
GET /ats/candidates/example
1curl "http://localhost:8000/ats/candidates/example"
1fetch("http://localhost:8000/ats/candidates/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/ats/candidates/example")
4print(response.json())
200 Example Response
No Body
GET /ats/candidates/:candidate_id/activities undocumented

/ats/candidates/:candidate_id/activities

Handled by api_list_activities
Parameters
candidate_id string · path
required
Responses
200Successful Response
GET /ats/candidates/example/activities
1curl "http://localhost:8000/ats/candidates/example/activities"
1fetch("http://localhost:8000/ats/candidates/example/activities")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/ats/candidates/example/activities")
4print(response.json())
200 Example Response
No Body
GET /ats/candidates/:candidate_id/resume undocumented

/ats/candidates/:candidate_id/resume

Handled by api_download_resume
Parameters
candidate_id string · path
required
Responses
200Successful Response
GET /ats/candidates/example/resume
1curl "http://localhost:8000/ats/candidates/example/resume"
1fetch("http://localhost:8000/ats/candidates/example/resume")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/ats/candidates/example/resume")
4print(response.json())
200 Example Response
No Body
GET /ats/candidates/:candidate_id/messages undocumented

/ats/candidates/:candidate_id/messages

Handled by api_list_candidate_messages
Parameters
candidate_id string · path
required
Responses
200Successful Response
GET /ats/candidates/example/messages
1curl "http://localhost:8000/ats/candidates/example/messages"
1fetch("http://localhost:8000/ats/candidates/example/messages")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/ats/candidates/example/messages")
4print(response.json())
200 Example Response
No Body
GET /ats/applications undocumented

/ats/applications

Handled by api_list_applications
Responses
200Successful Response
GET /ats/applications
1curl "http://localhost:8000/ats/applications"
1fetch("http://localhost:8000/ats/applications")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/ats/applications")
4print(response.json())
200 Example Response
No Body
GET /ats/applications/:application_id undocumented

/ats/applications/:application_id

Handled by api_get_application
Parameters
application_id string · path
required
Responses
200Successful Response
GET /ats/applications/example
1curl "http://localhost:8000/ats/applications/example"
1fetch("http://localhost:8000/ats/applications/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/ats/applications/example")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_application_summary
Parameters
application_id string · path
required
Responses
200Successful Response
GET /ats/applications/example/summary
1curl "http://localhost:8000/ats/applications/example/summary"
1fetch("http://localhost:8000/ats/applications/example/summary")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/ats/applications/example/summary")
4print(response.json())
200 Example Response
No Body
GET /ats/applications/:application_id/interviews undocumented

/ats/applications/:application_id/interviews

Handled by api_list_interviews
Parameters
application_id string · path
required
Responses
200Successful Response
GET /ats/applications/example/interviews
1curl "http://localhost:8000/ats/applications/example/interviews"
1fetch("http://localhost:8000/ats/applications/example/interviews")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/ats/applications/example/interviews")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_my_evaluations
Responses
200Successful Response
GET /ats/evaluations/mine
1curl "http://localhost:8000/ats/evaluations/mine"
1fetch("http://localhost:8000/ats/evaluations/mine")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/ats/evaluations/mine")
4print(response.json())
200 Example Response
No Body
GET /ats/applications/:application_id/evaluations undocumented

/ats/applications/:application_id/evaluations

Every scorecard on an application, anti-anchored in the query.

Handled by api_list_evaluations
Parameters
application_id string · path
required
Responses
200Successful Response
GET /ats/applications/example/evaluations
1curl "http://localhost:8000/ats/applications/example/evaluations"
1fetch("http://localhost:8000/ats/applications/example/evaluations")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/ats/applications/example/evaluations")
4print(response.json())
200 Example Response
No Body
GET /ats/evaluations/:evaluation_id undocumented

/ats/evaluations/:evaluation_id

Handled by api_get_evaluation
Parameters
evaluation_id string · path
required
Responses
200Successful Response
GET /ats/evaluations/example
1curl "http://localhost:8000/ats/evaluations/example"
1fetch("http://localhost:8000/ats/evaluations/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/ats/evaluations/example")
4print(response.json())
200 Example Response
No Body
GET /ats/applications/:application_id/offers undocumented

/ats/applications/:application_id/offers

Handled by api_list_offers
Parameters
application_id string · path
required
Responses
200Successful Response
GET /ats/applications/example/offers
1curl "http://localhost:8000/ats/applications/example/offers"
1fetch("http://localhost:8000/ats/applications/example/offers")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/ats/applications/example/offers")
4print(response.json())
200 Example Response
No Body
GET /ats/offers/:offer_id undocumented

/ats/offers/:offer_id

Handled by api_get_offer
Parameters
offer_id string · path
required
Responses
200Successful Response
GET /ats/offers/example
1curl "http://localhost:8000/ats/offers/example"
1fetch("http://localhost:8000/ats/offers/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/ats/offers/example")
4print(response.json())
200 Example Response
No Body
GET /ats/templates undocumented

/ats/templates

Handled by api_list_templates
Responses
200Successful Response
GET /ats/templates
1curl "http://localhost:8000/ats/templates"
1fetch("http://localhost:8000/ats/templates")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/ats/templates")
4print(response.json())
200 Example Response
No Body
GET /ats/templates/:template_id undocumented

/ats/templates/:template_id

Handled by api_get_template
Parameters
template_id string · path
required
Responses
200Successful Response
GET /ats/templates/example
1curl "http://localhost:8000/ats/templates/example"
1fetch("http://localhost:8000/ats/templates/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/ats/templates/example")
4print(response.json())
200 Example Response
No Body
GET /ats/templates/:template_id/preview undocumented

/ats/templates/:template_id/preview

What this template says about this candidate, without sending it.

Handled by api_preview_template
Parameters
template_id string · path
required
Responses
200Successful Response
GET /ats/templates/example/preview
1curl "http://localhost:8000/ats/templates/example/preview"
1fetch("http://localhost:8000/ats/templates/example/preview")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/ats/templates/example/preview")
4print(response.json())
200 Example Response
No Body
GET /ats/reports/:report_key undocumented

/ats/reports/:report_key

One report, named by ``report_key``. Authorization ran in authz.py.

Handled by api_report
Parameters
report_key string · path
required
Responses
200Successful Response
GET /ats/reports/example
1curl "http://localhost:8000/ats/reports/example"
1fetch("http://localhost:8000/ats/reports/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/ats/reports/example")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_list_careers_mailboxes
Responses
200Successful Response
GET /ats/settings/mailboxes
1curl "http://localhost:8000/ats/settings/mailboxes"
1fetch("http://localhost:8000/ats/settings/mailboxes")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/ats/settings/mailboxes")
4print(response.json())
200 Example Response
No Body
POST /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.

Handled by api_rotate_embed_key
Parameters
embed_id string · path
required
Responses
200Successful Response
POST /ats/settings/embeds/example/rotate-key
1curl -X POST "http://localhost:8000/ats/settings/embeds/example/rotate-key"
1fetch("http://localhost:8000/ats/settings/embeds/example/rotate-key", { method: "POST" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.post("http://localhost:8000/ats/settings/embeds/example/rotate-key")
4print(response.json())
200 Example Response
No Body
DELETE /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.

Handled by api_delete_location
Parameters
id string · path
required
Responses
200Successful Response
DELETE /attendance/locations/example
1curl -X DELETE "http://localhost:8000/attendance/locations/example"
1fetch("http://localhost:8000/attendance/locations/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/attendance/locations/example")
4print(response.json())
200 Example Response
No Body
GET /attendance/status undocumented

/attendance/status

Handled by api_get_status
Responses
200Successful Response
GET /attendance/status
1curl "http://localhost:8000/attendance/status"
1fetch("http://localhost:8000/attendance/status")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/attendance/status")
4print(response.json())
200 Example Response
No Body
GET /attendance/entries undocumented

/attendance/entries

Handled by api_list_entries
Responses
200Successful Response
GET /attendance/entries
1curl "http://localhost:8000/attendance/entries"
1fetch("http://localhost:8000/attendance/entries")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/attendance/entries")
4print(response.json())
200 Example Response
No Body
GET /attendance/timesheets undocumented

/attendance/timesheets

Handled by api_list_timesheets
Responses
200Successful Response
GET /attendance/timesheets
1curl "http://localhost:8000/attendance/timesheets"
1fetch("http://localhost:8000/attendance/timesheets")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/attendance/timesheets")
4print(response.json())
200 Example Response
No Body
GET /attendance/timesheets/:id undocumented

/attendance/timesheets/:id

Handled by api_get_timesheet
Parameters
id string · path
required
Responses
200Successful Response
GET /attendance/timesheets/example
1curl "http://localhost:8000/attendance/timesheets/example"
1fetch("http://localhost:8000/attendance/timesheets/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/attendance/timesheets/example")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_search_timezones
Responses
200Successful Response
GET /attendance/timezones
1curl "http://localhost:8000/attendance/timezones"
1fetch("http://localhost:8000/attendance/timezones")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/attendance/timezones")
4print(response.json())
200 Example Response
No Body
GET /attendance/locations undocumented

/attendance/locations

Handled by api_list_locations
Responses
200Successful Response
GET /attendance/locations
1curl "http://localhost:8000/attendance/locations"
1fetch("http://localhost:8000/attendance/locations")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/attendance/locations")
4print(response.json())
200 Example Response
No Body
PATCH /attendance/timesheets/:id

Update a timesheet

Handled by api_update_timesheet
Parameters
id string · path
required
Body · UpdateTimesheetapplication/json
status string · min length: 1 · max length: 20
required
propertyName anything
Responses
200Successful Response
PATCH /attendance/timesheets/example
1curl -X PATCH "http://localhost:8000/attendance/timesheets/example" \
2 -H "Content-Type: application/json" \
3 -d '{"status":"string"}'
1fetch("http://localhost:8000/attendance/timesheets/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "status": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/attendance/timesheets/example",
5 json={"status":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /attendance/locations/:id

Update a location

Handled by api_update_location
Parameters
id string · path
required
Body · UpdateLocationapplication/json
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
Responses
200Successful Response
PATCH /attendance/locations/example
1curl -X PATCH "http://localhost:8000/attendance/locations/example" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","timezone":"string","workdays":null,"work_start":"string","work_end":"string","is_default":null}'
1fetch("http://localhost:8000/attendance/locations/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "timezone": "string",
7 "workdays": null,
8 "work_start": "string",
9 "work_end": "string",
10 "is_default": null
11}),
12})
13 .then((res) => res.json())
14 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/attendance/locations/example",
5 json={"name":"string","timezone":"string","workdays":null,"work_start":"string","work_end":"string","is_default":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /attendance/clock-ins

Clock in

Handled by api_clock_in
Body · ClockInapplication/json
note string · max length: 500
source string · max length: 50
propertyName anything
Responses
200Successful Response
POST /attendance/clock-ins
1curl -X POST "http://localhost:8000/attendance/clock-ins" \
2 -H "Content-Type: application/json" \
3 -d '{"note":"string","source":"string"}'
1fetch("http://localhost:8000/attendance/clock-ins", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "note": "string",
6 "source": "string"
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/attendance/clock-ins",
5 json={"note":"string","source":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /attendance/clock-outs

Clock out

Handled by api_clock_out
Body · ClockOutapplication/json
note string · max length: 500
propertyName anything
Responses
200Successful Response
POST /attendance/clock-outs
1curl -X POST "http://localhost:8000/attendance/clock-outs" \
2 -H "Content-Type: application/json" \
3 -d '{"note":"string"}'
1fetch("http://localhost:8000/attendance/clock-outs", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "note": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/attendance/clock-outs",
5 json={"note":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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.

Handled by api_create_pings
Body · CreatePingsapplication/json
pings array
required
propertyName anything
Responses
200Successful Response
POST /attendance/pings
1curl -X POST "http://localhost:8000/attendance/pings" \
2 -H "Content-Type: application/json" \
3 -d '{"pings":[{"latitude":1.5,"longitude":1.5,"accuracy_m":1.5,"recorded_at":"2024-01-01T12:00:00Z"}]}'
1fetch("http://localhost:8000/attendance/pings", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "pings": [
6 {
7 "latitude": 1.5,
8 "longitude": 1.5,
9 "accuracy_m": 1.5,
10 "recorded_at": "2024-01-01T12:00:00Z"
11 }
12 ]
13}),
14})
15 .then((res) => res.json())
16 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/attendance/pings",
5 json={"pings":[{"latitude":1.5,"longitude":1.5,"accuracy_m":1.5,"recorded_at":"2024-01-01T12:00:00Z"}]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /attendance/locations

Create a location

Handled by api_create_location
Body · CreateLocationapplication/json
name string · min length: 1 · max length: 120
required
timezone string · min length: 1 · max length: 64
required
workdays
work_start string · max length: 5
work_end string · max length: 5
is_default
propertyName anything
Responses
200Successful Response
POST /attendance/locations
1curl -X POST "http://localhost:8000/attendance/locations" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","timezone":"string","workdays":null,"work_start":"string","work_end":"string","is_default":null}'
1fetch("http://localhost:8000/attendance/locations", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "timezone": "string",
7 "workdays": null,
8 "work_start": "string",
9 "work_end": "string",
10 "is_default": null
11}),
12})
13 .then((res) => res.json())
14 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/attendance/locations",
5 json={"name":"string","timezone":"string","workdays":null,"work_start":"string","work_end":"string","is_default":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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.

Handled by request_sign_in_link
Body · SignInRequestapplication/json
email string · min length: 1 · email
required
workspace string · min length: 1 · max length: 100
required
propertyName anything
Responses
200Successful Response
POST /sessions/links
1curl -X POST "http://localhost:8000/sessions/links" \
2 -H "Content-Type: application/json" \
3 -d '{"email":"user@example.com","workspace":"string"}'
1fetch("http://localhost:8000/sessions/links", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "email": "user@example.com",
6 "workspace": "string"
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/sessions/links",
5 json={"email":"user@example.com","workspace":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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.

Handled by login
Body · Loginapplication/json
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
Responses
200Successful Response
POST /sessions
1curl -X POST "http://localhost:8000/sessions" \
2 -H "Content-Type: application/json" \
3 -d '{"email":"user@example.com","workspace":"string","password":"string","token":"string","totp":"string","is_recovery_code":null}'
1fetch("http://localhost:8000/sessions", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "email": "user@example.com",
6 "workspace": "string",
7 "password": "string",
8 "token": "string",
9 "totp": "string",
10 "is_recovery_code": null
11}),
12})
13 .then((res) => res.json())
14 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/sessions",
5 json={"email":"user@example.com","workspace":"string","password":"string","token":"string","totp":"string","is_recovery_code":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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.

Handled by lookup_workspace
Body · WorkspaceLookupapplication/json
slug string · min length: 1 · max length: 100
required
propertyName anything
Responses
200Successful Response
POST /workspaces/lookup
1curl -X POST "http://localhost:8000/workspaces/lookup" \
2 -H "Content-Type: application/json" \
3 -d '{"slug":"string"}'
1fetch("http://localhost:8000/workspaces/lookup", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "slug": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/workspaces/lookup",
5 json={"slug":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /workspaces

Sign up

Handled by signup
Body · Signupapplication/json
company_name string · min length: 1 · max length: 200
required
full_name string · min length: 1 · max length: 200
required
email string · min length: 1 · email
required
terms_agreed
required
company_location string
industry string
company_size string
job_title string
propertyName anything
Responses
200Successful Response
POST /workspaces
1curl -X POST "http://localhost:8000/workspaces" \
2 -H "Content-Type: application/json" \
3 -d '{"company_name":"string","full_name":"string","email":"user@example.com","terms_agreed":null,"company_location":"string","industry":"string","company_size":"string","job_title":"string"}'
1fetch("http://localhost:8000/workspaces", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "company_name": "string",
6 "full_name": "string",
7 "email": "user@example.com",
8 "terms_agreed": null,
9 "company_location": "string",
10 "industry": "string",
11 "company_size": "string",
12 "job_title": "string"
13}),
14})
15 .then((res) => res.json())
16 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/workspaces",
5 json={"company_name":"string","full_name":"string","email":"user@example.com","terms_agreed":null,"company_location":"string","industry":"string","company_size":"string","job_title":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /verifications

Verify OTP

Handled by verify
Body · Verifyapplication/json
code string · min length: 1
required
password string · min length: 8
required
propertyName anything
Responses
200Successful Response
POST /verifications
1curl -X POST "http://localhost:8000/verifications" \
2 -H "Content-Type: application/json" \
3 -d '{"code":"string","password":"string"}'
1fetch("http://localhost:8000/verifications", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "code": "string",
6 "password": "string"
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/verifications",
5 json={"code":"string","password":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /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.

Handled by accept_invitation
Parameters
token string · path
required
Body · AcceptInvitationapplication/json
password string · min length: 8
required
totp string · min length: 6 · max length: 8
propertyName anything
Responses
200Successful Response
PUT /invitations/example
1curl -X PUT "http://localhost:8000/invitations/example" \
2 -H "Content-Type: application/json" \
3 -d '{"password":"string","totp":"string"}'
1fetch("http://localhost:8000/invitations/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "password": "string",
6 "totp": "string"
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/invitations/example",
5 json={"password":"string","totp":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /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.

Handled by set_password
Parameters
token string · path
required
Body · SetPasswordapplication/json
password string · min length: 8
required
propertyName anything
Responses
200Successful Response
PUT /password-resets/example
1curl -X PUT "http://localhost:8000/password-resets/example" \
2 -H "Content-Type: application/json" \
3 -d '{"password":"string"}'
1fetch("http://localhost:8000/password-resets/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "password": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/password-resets/example",
5 json={"password":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
DELETE /avatars/:member_id undocumented

/avatars/:member_id

DELETE /avatars/:member_id — clear avatar, revert to initials.

Handled by remove_avatar
Parameters
member_id string · path
required
Responses
200Successful Response
DELETE /avatars/example
1curl -X DELETE "http://localhost:8000/avatars/example"
1fetch("http://localhost:8000/avatars/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/avatars/example")
4print(response.json())
200 Example Response
No Body
POST /avatars/:member_id undocumented

/avatars/:member_id

POST /avatars/:member_id — upload profile avatar to R2.

Handled by upload_avatar
Parameters
member_id string · path
required
Responses
200Successful Response
POST /avatars/example
1curl -X POST "http://localhost:8000/avatars/example"
1fetch("http://localhost:8000/avatars/example", { method: "POST" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.post("http://localhost:8000/avatars/example")
4print(response.json())
200 Example Response
No Body
POST /payment-methods

Add payment method

POST /accounts/billing/payment-methods — Add a payment method via Flutterwave v4.

Handled by api_add_payment_method
Body · AddPaymentMethodapplication/json
card_number string · min length: 13 · max length: 19
required
expiry_month string · min length: 1 · max length: 2
required
expiry_year string · min length: 2 · max length: 4
required
cvv string · min length: 3 · max length: 4
required
propertyName anything
Responses
200Successful Response
POST /payment-methods
1curl -X POST "http://localhost:8000/payment-methods" \
2 -H "Content-Type: application/json" \
3 -d '{"card_number":"string","expiry_month":"string","expiry_year":"string","cvv":"string"}'
1fetch("http://localhost:8000/payment-methods", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "card_number": "string",
6 "expiry_month": "string",
7 "expiry_year": "string",
8 "cvv": "string"
9}),
10})
11 .then((res) => res.json())
12 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/payment-methods",
5 json={"card_number":"string","expiry_month":"string","expiry_year":"string","cvv":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /plan

Switch plan

PUT /plan: switch plan immediately, with upgrade proration.

Handled by api_switch_plan
Body · SwitchPlanapplication/json
plan
required
propertyName anything
Responses
200Successful Response
PUT /plan
1curl -X PUT "http://localhost:8000/plan" \
2 -H "Content-Type: application/json" \
3 -d '{"plan":null}'
1fetch("http://localhost:8000/plan", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "plan": null
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/plan",
5 json={"plan":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /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.

Handled by api_update_billing_interval
Body · UpdateBillingIntervalapplication/json
billing_interval
required
propertyName anything
Responses
200Successful Response
PUT /plan/interval
1curl -X PUT "http://localhost:8000/plan/interval" \
2 -H "Content-Type: application/json" \
3 -d '{"billing_interval":null}'
1fetch("http://localhost:8000/plan/interval", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "billing_interval": null
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/plan/interval",
5 json={"billing_interval":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /finance/bills/:entry_id

Receive/approve/void a bill

Handled by api_patch_bill
Parameters
entry_id string · path
required
Body · UpdateBillStatusapplication/json
status
required
propertyName anything
Responses
200Successful Response
PATCH /finance/bills/example
1curl -X PATCH "http://localhost:8000/finance/bills/example" \
2 -H "Content-Type: application/json" \
3 -d '{"status":null}'
1fetch("http://localhost:8000/finance/bills/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "status": null
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/finance/bills/example",
5 json={"status":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /finance/bills

Create a bill

Handled by api_create_bill
Body · CreateBillapplication/json
date string · min length: 10
required
items array
company_mrn string
contact_mrn string
currency
required
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
Responses
200Successful Response
POST /finance/bills
1curl -X POST "http://localhost:8000/finance/bills" \
2 -H "Content-Type: application/json" \
3 -d '{"date":"string","items":[{"description":"string","quantity":1.5,"unit_price":1.5,"discount":1.5,"amount":1.5,"account_code":"string","product_mrn":"string","taxes":[{"name":"string","rate":1.5,"amount":1.5,"reverse_charge":null}]}],"company_mrn":"string","contact_mrn":"string","currency":null,"exchange_rate":1.5,"due_date":"string","memo":"string","tags":["string"],"sources":["string"],"adjustments":[{"label":"string","type":null,"value":1.5,"amount":1.5,"account_code":"string"}],"dimensions":null,"idempotency_key":"string"}'
1fetch("http://localhost:8000/finance/bills", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "date": "string",
6 "items": [
7 {
8 "description": "string",
9 "quantity": 1.5,
10 "unit_price": 1.5,
11 "discount": 1.5,
12 "amount": 1.5,
13 "account_code": "string",
14 "product_mrn": "string",
15 "taxes": [
16 {
17 "name": "string",
18 "rate": 1.5,
19 "amount": 1.5,
20 "reverse_charge": null
21 }
22 ]
23 }
24 ],
25 "company_mrn": "string",
26 "contact_mrn": "string",
27 "currency": null,
28 "exchange_rate": 1.5,
29 "due_date": "string",
30 "memo": "string",
31 "tags": [
32 "string"
33 ],
34 "sources": [
35 "string"
36 ],
37 "adjustments": [
38 {
39 "label": "string",
40 "type": null,
41 "value": 1.5,
42 "amount": 1.5,
43 "account_code": "string"
44 }
45 ],
46 "dimensions": null,
47 "idempotency_key": "string"
48}),
49})
50 .then((res) => res.json())
51 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/finance/bills",
5 json={"date":"string","items":[{"description":"string","quantity":1.5,"unit_price":1.5,"discount":1.5,"amount":1.5,"account_code":"string","product_mrn":"string","taxes":[{"name":"string","rate":1.5,"amount":1.5,"reverse_charge":null}]}],"company_mrn":"string","contact_mrn":"string","currency":null,"exchange_rate":1.5,"due_date":"string","memo":"string","tags":["string"],"sources":["string"],"adjustments":[{"label":"string","type":null,"value":1.5,"amount":1.5,"account_code":"string"}],"dimensions":null,"idempotency_key":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /finance/bills/:entry_id

Update a draft bill

Handled by api_update_bill
Parameters
entry_id string · path
required
Body · UpdateBillapplication/json
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
Responses
200Successful Response
PUT /finance/bills/example
1curl -X PUT "http://localhost:8000/finance/bills/example" \
2 -H "Content-Type: application/json" \
3 -d '{"date":"string","items":[{"description":"string","quantity":1.5,"unit_price":1.5,"discount":1.5,"amount":1.5,"account_code":"string","product_mrn":"string","taxes":[{"name":"string","rate":1.5,"amount":1.5,"reverse_charge":null}]}],"company_mrn":"string","contact_mrn":"string","currency":null,"exchange_rate":1.5,"due_date":"string","memo":"string","tags":["string"],"adjustments":[{"label":"string","type":null,"value":1.5,"amount":1.5,"account_code":"string"}],"dimensions":null}'
1fetch("http://localhost:8000/finance/bills/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "date": "string",
6 "items": [
7 {
8 "description": "string",
9 "quantity": 1.5,
10 "unit_price": 1.5,
11 "discount": 1.5,
12 "amount": 1.5,
13 "account_code": "string",
14 "product_mrn": "string",
15 "taxes": [
16 {
17 "name": "string",
18 "rate": 1.5,
19 "amount": 1.5,
20 "reverse_charge": null
21 }
22 ]
23 }
24 ],
25 "company_mrn": "string",
26 "contact_mrn": "string",
27 "currency": null,
28 "exchange_rate": 1.5,
29 "due_date": "string",
30 "memo": "string",
31 "tags": [
32 "string"
33 ],
34 "adjustments": [
35 {
36 "label": "string",
37 "type": null,
38 "value": 1.5,
39 "amount": 1.5,
40 "account_code": "string"
41 }
42 ],
43 "dimensions": null
44}),
45})
46 .then((res) => res.json())
47 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/finance/bills/example",
5 json={"date":"string","items":[{"description":"string","quantity":1.5,"unit_price":1.5,"discount":1.5,"amount":1.5,"account_code":"string","product_mrn":"string","taxes":[{"name":"string","rate":1.5,"amount":1.5,"reverse_charge":null}]}],"company_mrn":"string","contact_mrn":"string","currency":null,"exchange_rate":1.5,"due_date":"string","memo":"string","tags":["string"],"adjustments":[{"label":"string","type":null,"value":1.5,"amount":1.5,"account_code":"string"}],"dimensions":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
DELETE /boards/:board_id/tasks/:task_id undocumented

/boards/:board_id/tasks/:task_id

Return a single task from the board to the incubator.

Handled by api_return_to_incubator
Parameters
board_id string · path
required
task_id string · path
required
Responses
200Successful Response
DELETE /boards/example/tasks/example
1curl -X DELETE "http://localhost:8000/boards/example/tasks/example"
1fetch("http://localhost:8000/boards/example/tasks/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/boards/example/tasks/example")
4print(response.json())
200 Example Response
No Body
DELETE /boards/:board_id/tasks undocumented

/boards/:board_id/tasks

DELETE /boards/:board_id/tasks?scheduled=false — clear unplanned tasks from board.

Handled by api_clear_unplanned
Parameters
board_id string · path
required
Responses
200Successful Response
DELETE /boards/example/tasks
1curl -X DELETE "http://localhost:8000/boards/example/tasks"
1fetch("http://localhost:8000/boards/example/tasks", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/boards/example/tasks")
4print(response.json())
200 Example Response
No Body
DELETE /boards/:board_id

Delete a board

Handled by api_delete_board
Parameters
board_id string · path
required
Body · DeleteBoardapplication/json
confirm_key string · min length: 1
required
propertyName anything
Responses
200Successful Response
DELETE /boards/example
1curl -X DELETE "http://localhost:8000/boards/example" \
2 -H "Content-Type: application/json" \
3 -d '{"confirm_key":"string"}'
1fetch("http://localhost:8000/boards/example", {
2 method: "DELETE",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "confirm_key": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.delete(
4 "http://localhost:8000/boards/example",
5 json={"confirm_key":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
DELETE /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.

Handled by api_delete_topic
Parameters
board_id string · path
required
topic_id string · path
required
Responses
200Successful Response
DELETE /boards/example/topics/example
1curl -X DELETE "http://localhost:8000/boards/example/topics/example"
1fetch("http://localhost:8000/boards/example/topics/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/boards/example/topics/example")
4print(response.json())
200 Example Response
No Body
DELETE /boards/:board_id/members/:member_id undocumented

/boards/:board_id/members/:member_id

Handled by api_remove_board_member
Parameters
board_id string · path
required
member_id string · path
required
Responses
200Successful Response
DELETE /boards/example/members/example
1curl -X DELETE "http://localhost:8000/boards/example/members/example"
1fetch("http://localhost:8000/boards/example/members/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/boards/example/members/example")
4print(response.json())
200 Example Response
No Body
GET /boards undocumented

/boards

Handled by api_list_boards
Responses
200Successful Response
GET /boards
1curl "http://localhost:8000/boards"
1fetch("http://localhost:8000/boards")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/boards")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_list_task_filters
Parameters
board_id string · path
required
Responses
200Successful Response
GET /boards/example/task-filters
1curl "http://localhost:8000/boards/example/task-filters"
1fetch("http://localhost:8000/boards/example/task-filters")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/boards/example/task-filters")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_list_task_filter_options
Parameters
board_id string · path
required
key string · path
required
Responses
200Successful Response
GET /boards/example/task-filters/example/options
1curl "http://localhost:8000/boards/example/task-filters/example/options"
1fetch("http://localhost:8000/boards/example/task-filters/example/options")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/boards/example/task-filters/example/options")
4print(response.json())
200 Example Response
No Body
GET /boards/:board_id/topics undocumented

/boards/:board_id/topics

GET /boards/:board_id/topics?q=...: a board's topics.

Handled by api_list_topics
Parameters
board_id string · path
required
Responses
200Successful Response
GET /boards/example/topics
1curl "http://localhost:8000/boards/example/topics"
1fetch("http://localhost:8000/boards/example/topics")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/boards/example/topics")
4print(response.json())
200 Example Response
No Body
GET /boards/:board_id/members undocumented

/boards/:board_id/members

Handled by api_list_board_members
Parameters
board_id string · path
required
Responses
200Successful Response
GET /boards/example/members
1curl "http://localhost:8000/boards/example/members"
1fetch("http://localhost:8000/boards/example/members")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/boards/example/members")
4print(response.json())
200 Example Response
No Body
PATCH /boards/:board_id/columns

Rename a board column

Rename a board column (lane) and update all tasks referencing it.

Handled by api_rename_lane
Parameters
board_id string · path
required
Body · RenameColumnapplication/json
old_name string · min length: 1
required
new_name string · min length: 1
required
propertyName anything
Responses
200Successful Response
PATCH /boards/example/columns
1curl -X PATCH "http://localhost:8000/boards/example/columns" \
2 -H "Content-Type: application/json" \
3 -d '{"old_name":"string","new_name":"string"}'
1fetch("http://localhost:8000/boards/example/columns", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "old_name": "string",
6 "new_name": "string"
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/boards/example/columns",
5 json={"old_name":"string","new_name":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /boards/:board_id/members/:member_id

Change a project member's role

Handled by api_update_board_member
Parameters
board_id string · path
required
member_id string · path
required
Body · UpdateBoardMemberapplication/json
role
required
propertyName anything
Responses
200Successful Response
PATCH /boards/example/members/example
1curl -X PATCH "http://localhost:8000/boards/example/members/example" \
2 -H "Content-Type: application/json" \
3 -d '{"role":null}'
1fetch("http://localhost:8000/boards/example/members/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "role": null
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/boards/example/members/example",
5 json={"role":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /boards

Create a board

Handled by api_create_board
Body · CreateBoardapplication/json
title string · min length: 1 · max length: 200
required
description string · max length: 2000
template_id string
is_template
grid object
propertyName anything
Responses
200Successful Response
POST /boards
1curl -X POST "http://localhost:8000/boards" \
2 -H "Content-Type: application/json" \
3 -d '{"title":"string","description":"string","template_id":"string","is_template":null,"grid":{"mode":null,"spacing":1,"snap":null,"background":"string","default_sticky_color":"string"}}'
1fetch("http://localhost:8000/boards", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "title": "string",
6 "description": "string",
7 "template_id": "string",
8 "is_template": null,
9 "grid": {
10 "mode": null,
11 "spacing": 1,
12 "snap": null,
13 "background": "string",
14 "default_sticky_color": "string"
15 }
16}),
17})
18 .then((res) => res.json())
19 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/boards",
5 json={"title":"string","description":"string","template_id":"string","is_template":null,"grid":{"mode":null,"spacing":1,"snap":null,"background":"string","default_sticky_color":"string"}},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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.

Handled by api_pull_tasks
Parameters
board_id string · path
required
Body · PullTasksapplication/json
task_ids array
schedule_id string
propertyName anything
Responses
200Successful Response
POST /boards/example/tasks
1curl -X POST "http://localhost:8000/boards/example/tasks" \
2 -H "Content-Type: application/json" \
3 -d '{"task_ids":["string"],"schedule_id":"string"}'
1fetch("http://localhost:8000/boards/example/tasks", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "task_ids": [
6 "string"
7 ],
8 "schedule_id": "string"
9}),
10})
11 .then((res) => res.json())
12 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/boards/example/tasks",
5 json={"task_ids":["string"],"schedule_id":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /boards/:board_id/members

Add a project member

Handled by api_add_board_member
Parameters
board_id string · path
required
Body · AddBoardMemberapplication/json
member_id string · min length: 1
required
role
required
propertyName anything
Responses
200Successful Response
POST /boards/example/members
1curl -X POST "http://localhost:8000/boards/example/members" \
2 -H "Content-Type: application/json" \
3 -d '{"member_id":"string","role":null}'
1fetch("http://localhost:8000/boards/example/members", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "member_id": "string",
6 "role": null
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/boards/example/members",
5 json={"member_id":"string","role":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /views

Save a board view

Handled by api_create_saved_view
Body · CreateSavedViewapplication/json
board_id string
required
name string · min length: 1 · max length: 80
required
tab string · min length: 1 · max length: 40
required
schedule_id string
propertyName anything
Responses
200Successful Response
POST /views
1curl -X POST "http://localhost:8000/views" \
2 -H "Content-Type: application/json" \
3 -d '{"board_id":"string","name":"string","tab":"string","schedule_id":"string"}'
1fetch("http://localhost:8000/views", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "board_id": "string",
6 "name": "string",
7 "tab": "string",
8 "schedule_id": "string"
9}),
10})
11 .then((res) => res.json())
12 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/views",
5 json={"board_id":"string","name":"string","tab":"string","schedule_id":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /boards/:board_id

Update board settings

Update board settings (name, description, columns).

Handled by api_update_board
Parameters
board_id string · path
required
Body · UpdateBoardapplication/json
deleted
title string · min length: 1 · max length: 200
description string · max length: 2000
grid object
propertyName anything
Responses
200Successful Response
PUT /boards/example
1curl -X PUT "http://localhost:8000/boards/example" \
2 -H "Content-Type: application/json" \
3 -d '{"deleted":null,"title":"string","description":"string","grid":{"mode":null,"spacing":1,"snap":null,"background":"string","default_sticky_color":"string"}}'
1fetch("http://localhost:8000/boards/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "deleted": null,
6 "title": "string",
7 "description": "string",
8 "grid": {
9 "mode": null,
10 "spacing": 1,
11 "snap": null,
12 "background": "string",
13 "default_sticky_color": "string"
14 }
15}),
16})
17 .then((res) => res.json())
18 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/boards/example",
5 json={"deleted":null,"title":"string","description":"string","grid":{"mode":null,"spacing":1,"snap":null,"background":"string","default_sticky_color":"string"}},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /finance/budgets/:budget_id

Update a budget

Handled by handler
Parameters
budget_id string · path
required
Body · BudgetEntryapplication/json
account_id string · min length: 1
required
period_start string · min length: 10
required
period_end string · min length: 10
required
amount number
required
dimensions object
notes string · max length: 2000
propertyName anything
Responses
200Successful Response
PATCH /finance/budgets/example
1curl -X PATCH "http://localhost:8000/finance/budgets/example" \
2 -H "Content-Type: application/json" \
3 -d '{"account_id":"string","period_start":"string","period_end":"string","amount":1.5,"dimensions":{"department":"string","location":"string","project":"string"},"notes":"string"}'
1fetch("http://localhost:8000/finance/budgets/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "account_id": "string",
6 "period_start": "string",
7 "period_end": "string",
8 "amount": 1.5,
9 "dimensions": {
10 "department": "string",
11 "location": "string",
12 "project": "string"
13 },
14 "notes": "string"
15}),
16})
17 .then((res) => res.json())
18 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/finance/budgets/example",
5 json={"account_id":"string","period_start":"string","period_end":"string","amount":1.5,"dimensions":{"department":"string","location":"string","project":"string"},"notes":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /finance/budgets

Create a budget

Handled by handler
Body · BudgetEntryapplication/json
account_id string · min length: 1
required
period_start string · min length: 10
required
period_end string · min length: 10
required
amount number
required
dimensions object
notes string · max length: 2000
propertyName anything
Responses
200Successful Response
POST /finance/budgets
1curl -X POST "http://localhost:8000/finance/budgets" \
2 -H "Content-Type: application/json" \
3 -d '{"account_id":"string","period_start":"string","period_end":"string","amount":1.5,"dimensions":{"department":"string","location":"string","project":"string"},"notes":"string"}'
1fetch("http://localhost:8000/finance/budgets", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "account_id": "string",
6 "period_start": "string",
7 "period_end": "string",
8 "amount": 1.5,
9 "dimensions": {
10 "department": "string",
11 "location": "string",
12 "project": "string"
13 },
14 "notes": "string"
15}),
16})
17 .then((res) => res.json())
18 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/finance/budgets",
5 json={"account_id":"string","period_start":"string","period_end":"string","amount":1.5,"dimensions":{"department":"string","location":"string","project":"string"},"notes":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
DELETE /calls/:id undocumented

/calls/:id

Handled by api_delete_call
Parameters
id string · path
required
Responses
200Successful Response
DELETE /calls/example
1curl -X DELETE "http://localhost:8000/calls/example"
1fetch("http://localhost:8000/calls/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/calls/example")
4print(response.json())
200 Example Response
No Body
DELETE /calls/:id/participants/:member_mrn undocumented

/calls/:id/participants/:member_mrn

Handled by api_remove_participant
Parameters
id string · path
required
member_mrn string · path
required
Responses
200Successful Response
DELETE /calls/example/participants/example
1curl -X DELETE "http://localhost:8000/calls/example/participants/example"
1fetch("http://localhost:8000/calls/example/participants/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/calls/example/participants/example")
4print(response.json())
200 Example Response
No Body
DELETE /calls/:id/sessions undocumented

/calls/:id/sessions

Handled by api_leave_call
Parameters
id string · path
required
Responses
200Successful Response
DELETE /calls/example/sessions
1curl -X DELETE "http://localhost:8000/calls/example/sessions"
1fetch("http://localhost:8000/calls/example/sessions", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/calls/example/sessions")
4print(response.json())
200 Example Response
No Body
DELETE /calls/:id/recordings/:recording_id undocumented

/calls/:id/recordings/:recording_id

Handled by api_delete_recording
Parameters
id string · path
required
recording_id string · path
required
Responses
200Successful Response
DELETE /calls/example/recordings/example
1curl -X DELETE "http://localhost:8000/calls/example/recordings/example"
1fetch("http://localhost:8000/calls/example/recordings/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/calls/example/recordings/example")
4print(response.json())
200 Example Response
No Body
GET /calls undocumented

/calls

Handled by api_list_calls
Responses
200Successful Response
GET /calls
1curl "http://localhost:8000/calls"
1fetch("http://localhost:8000/calls")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/calls")
4print(response.json())
200 Example Response
No Body
GET /calls/:id undocumented

/calls/:id

Handled by api_get_call
Parameters
id string · path
required
Responses
200Successful Response
GET /calls/example
1curl "http://localhost:8000/calls/example"
1fetch("http://localhost:8000/calls/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/calls/example")
4print(response.json())
200 Example Response
No Body
GET /calls/:id/participants undocumented

/calls/:id/participants

Handled by api_list_participants
Parameters
id string · path
required
Responses
200Successful Response
GET /calls/example/participants
1curl "http://localhost:8000/calls/example/participants"
1fetch("http://localhost:8000/calls/example/participants")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/calls/example/participants")
4print(response.json())
200 Example Response
No Body
GET /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

Handled by api_member_admission_status
Parameters
id string · path
required
Responses
200Successful Response
GET /calls/example/admission
1curl "http://localhost:8000/calls/example/admission"
1fetch("http://localhost:8000/calls/example/admission")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/calls/example/admission")
4print(response.json())
200 Example Response
No Body
GET /calls/:id/links undocumented

/calls/:id/links

Handled by api_list_links
Parameters
id string · path
required
Responses
200Successful Response
GET /calls/example/links
1curl "http://localhost:8000/calls/example/links"
1fetch("http://localhost:8000/calls/example/links")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/calls/example/links")
4print(response.json())
200 Example Response
No Body
GET /calls/:id/messages undocumented

/calls/:id/messages

Handled by api_list_messages
Parameters
id string · path
required
Responses
200Successful Response
GET /calls/example/messages
1curl "http://localhost:8000/calls/example/messages"
1fetch("http://localhost:8000/calls/example/messages")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/calls/example/messages")
4print(response.json())
200 Example Response
No Body
GET /calls/:id/recordings undocumented

/calls/:id/recordings

Handled by api_list_recordings
Parameters
id string · path
required
Responses
200Successful Response
GET /calls/example/recordings
1curl "http://localhost:8000/calls/example/recordings"
1fetch("http://localhost:8000/calls/example/recordings")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/calls/example/recordings")
4print(response.json())
200 Example Response
No Body
PATCH /calls/:id

Update a call

Handled by api_update_call
Parameters
id string · path
required
Body · UpdateCallapplication/json
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
Responses
200Successful Response
PATCH /calls/example
1curl -X PATCH "http://localhost:8000/calls/example" \
2 -H "Content-Type: application/json" \
3 -d '{"title":"string","scheduled_at":"string","status":null,"format":null,"access_policy":null,"settings":{"waiting_room":null,"allow_screen_share":null,"mute_on_join":null,"record":null},"attendees_can_mic":null,"attendees_can_camera":null,"attendees_can_screenshare":null,"attendees_can_chat":null,"hide_attendee_tiles":null}'
1fetch("http://localhost:8000/calls/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "title": "string",
6 "scheduled_at": "string",
7 "status": null,
8 "format": null,
9 "access_policy": null,
10 "settings": {
11 "waiting_room": null,
12 "allow_screen_share": null,
13 "mute_on_join": null,
14 "record": null
15 },
16 "attendees_can_mic": null,
17 "attendees_can_camera": null,
18 "attendees_can_screenshare": null,
19 "attendees_can_chat": null,
20 "hide_attendee_tiles": null
21}),
22})
23 .then((res) => res.json())
24 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/calls/example",
5 json={"title":"string","scheduled_at":"string","status":null,"format":null,"access_policy":null,"settings":{"waiting_room":null,"allow_screen_share":null,"mute_on_join":null,"record":null},"attendees_can_mic":null,"attendees_can_camera":null,"attendees_can_screenshare":null,"attendees_can_chat":null,"hide_attendee_tiles":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /calls

Create a call

Handled by api_create_call
Body · CreateCallapplication/json
type
required
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
Responses
200Successful Response
POST /calls
1curl -X POST "http://localhost:8000/calls" \
2 -H "Content-Type: application/json" \
3 -d '{"type":null,"mode":null,"format":null,"title":"string","participants":["string"],"source_mrn":"string","scheduled_at":"string","max_participants":1,"access_policy":null,"settings":{"waiting_room":null,"allow_screen_share":null,"mute_on_join":null,"record":null},"external_invitees_text":"string"}'
1fetch("http://localhost:8000/calls", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "type": null,
6 "mode": null,
7 "format": null,
8 "title": "string",
9 "participants": [
10 "string"
11 ],
12 "source_mrn": "string",
13 "scheduled_at": "string",
14 "max_participants": 1,
15 "access_policy": null,
16 "settings": {
17 "waiting_room": null,
18 "allow_screen_share": null,
19 "mute_on_join": null,
20 "record": null
21 },
22 "external_invitees_text": "string"
23}),
24})
25 .then((res) => res.json())
26 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/calls",
5 json={"type":null,"mode":null,"format":null,"title":"string","participants":["string"],"source_mrn":"string","scheduled_at":"string","max_participants":1,"access_policy":null,"settings":{"waiting_room":null,"allow_screen_share":null,"mute_on_join":null,"record":null},"external_invitees_text":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /calls/:id/sessions undocumented

/calls/:id/sessions

Handled by api_join_call
Parameters
id string · path
required
Responses
200Successful Response
POST /calls/example/sessions
1curl -X POST "http://localhost:8000/calls/example/sessions"
1fetch("http://localhost:8000/calls/example/sessions", { method: "POST" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.post("http://localhost:8000/calls/example/sessions")
4print(response.json())
200 Example Response
No Body
POST /calls/:id/sessions/leave undocumented

/calls/:id/sessions/leave

Handled by api_leave_call
Parameters
id string · path
required
Responses
200Successful Response
POST /calls/example/sessions/leave
1curl -X POST "http://localhost:8000/calls/example/sessions/leave"
1fetch("http://localhost:8000/calls/example/sessions/leave", { method: "POST" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.post("http://localhost:8000/calls/example/sessions/leave")
4print(response.json())
200 Example Response
No Body
POST /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.

Handled by api_refresh_call_token
Parameters
id string · path
required
Responses
200Successful Response
POST /calls/example/token
1curl -X POST "http://localhost:8000/calls/example/token"
1fetch("http://localhost:8000/calls/example/token", { method: "POST" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.post("http://localhost:8000/calls/example/token")
4print(response.json())
200 Example Response
No Body
POST /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.

Handled by api_upload_recording_part
Parameters
id string · path
required
recording_id string · path
required
Responses
200Successful Response
POST /calls/example/recordings/example/parts
1curl -X POST "http://localhost:8000/calls/example/recordings/example/parts"
1fetch("http://localhost:8000/calls/example/recordings/example/parts", { method: "POST" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.post("http://localhost:8000/calls/example/recordings/example/parts")
4print(response.json())
200 Example Response
No Body
POST /chats/:id/call-requests

Request a call from chat

POST /chats/:id/call-requests — ask the Calls app to start a call.

Handled by api_request_call
Parameters
id string · path
required
Body · RequestCallapplication/json
mode
propertyName anything
Responses
200Successful Response
POST /chats/example/call-requests
1curl -X POST "http://localhost:8000/chats/example/call-requests" \
2 -H "Content-Type: application/json" \
3 -d '{"mode":null}'
1fetch("http://localhost:8000/chats/example/call-requests", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "mode": null
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/chats/example/call-requests",
5 json={"mode":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
DELETE /canvas/boards/:board_id undocumented

/canvas/boards/:board_id

DELETE /canvas/boards/:board_id — soft-delete + drop grants (owner only).

Handled by api_delete_board
Parameters
board_id string · path
required
Responses
200Successful Response
DELETE /canvas/boards/example
1curl -X DELETE "http://localhost:8000/canvas/boards/example"
1fetch("http://localhost:8000/canvas/boards/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/canvas/boards/example")
4print(response.json())
200 Example Response
No Body
DELETE /canvas/trash undocumented

/canvas/trash

DELETE /canvas/trash: delete for good every trashed board the caller may purge.

Handled by api_empty_trash
Responses
200Successful Response
DELETE /canvas/trash
1curl -X DELETE "http://localhost:8000/canvas/trash"
1fetch("http://localhost:8000/canvas/trash", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/canvas/trash")
4print(response.json())
200 Example Response
No Body
DELETE /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.

Handled by api_purge_board
Parameters
board_id string · path
required
Responses
200Successful Response
DELETE /canvas/trash/example
1curl -X DELETE "http://localhost:8000/canvas/trash/example"
1fetch("http://localhost:8000/canvas/trash/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/canvas/trash/example")
4print(response.json())
200 Example Response
No Body
DELETE /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.

Handled by api_delete_comment
Parameters
board_id string · path
required
comment_id string · path
required
Responses
200Successful Response
DELETE /canvas/boards/example/comments/example
1curl -X DELETE "http://localhost:8000/canvas/boards/example/comments/example"
1fetch("http://localhost:8000/canvas/boards/example/comments/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/canvas/boards/example/comments/example")
4print(response.json())
200 Example Response
No Body
DELETE /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.

Handled by api_remove_vote
Parameters
board_id string · path
required
session_id string · path
required
object_id string · path
required
Responses
200Successful Response
DELETE /canvas/boards/example/vote-sessions/example/votes/example
1curl -X DELETE "http://localhost:8000/canvas/boards/example/vote-sessions/example/votes/example"
1fetch("http://localhost:8000/canvas/boards/example/vote-sessions/example/votes/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/canvas/boards/example/vote-sessions/example/votes/example")
4print(response.json())
200 Example Response
No Body
DELETE /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.

Handled by api_delete_export
Parameters
board_id string · path
required
target string · path
required
Responses
200Successful Response
DELETE /canvas/boards/example/exports/example
1curl -X DELETE "http://localhost:8000/canvas/boards/example/exports/example"
1fetch("http://localhost:8000/canvas/boards/example/exports/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/canvas/boards/example/exports/example")
4print(response.json())
200 Example Response
No Body
GET /canvas/boards undocumented

/canvas/boards

GET /canvas/boards — boards the caller can access. ?is_template=true filters templates.

Handled by api_list_boards
Responses
200Successful Response
GET /canvas/boards
1curl "http://localhost:8000/canvas/boards"
1fetch("http://localhost:8000/canvas/boards")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/canvas/boards")
4print(response.json())
200 Example Response
No Body
GET /canvas/templates undocumented

/canvas/templates

GET /canvas/templates — sugar for ?is_template=true.

Handled by api_list_templates
Responses
200Successful Response
GET /canvas/templates
1curl "http://localhost:8000/canvas/templates"
1fetch("http://localhost:8000/canvas/templates")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/canvas/templates")
4print(response.json())
200 Example Response
No Body
GET /canvas/boards/:board_id undocumented

/canvas/boards/:board_id

GET /canvas/boards/:board_id — board metadata (no content).

Handled by api_get_board
Parameters
board_id string · path
required
Responses
200Successful Response
GET /canvas/boards/example
1curl "http://localhost:8000/canvas/boards/example"
1fetch("http://localhost:8000/canvas/boards/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/canvas/boards/example")
4print(response.json())
200 Example Response
No Body
GET /canvas/trash undocumented

/canvas/trash

GET /canvas/trash: trashed boards the caller may restore or delete for good.

Handled by api_list_trash
Responses
200Successful Response
GET /canvas/trash
1curl "http://localhost:8000/canvas/trash"
1fetch("http://localhost:8000/canvas/trash")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/canvas/trash")
4print(response.json())
200 Example Response
No Body
GET /canvas/boards/:board_id/content undocumented

/canvas/boards/:board_id/content

GET /canvas/boards/:board_id/content — opaque board content to bootstrap the client.

Handled by api_get_content
Parameters
board_id string · path
required
Responses
200Successful Response
GET /canvas/boards/example/content
1curl "http://localhost:8000/canvas/boards/example/content"
1fetch("http://localhost:8000/canvas/boards/example/content")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/canvas/boards/example/content")
4print(response.json())
200 Example Response
No Body
GET /canvas/boards/:board_id/comments undocumented

/canvas/boards/:board_id/comments

GET /canvas/boards/:board_id/comments — threaded comments for a board.

Handled by api_list_comments
Parameters
board_id string · path
required
Responses
200Successful Response
GET /canvas/boards/example/comments
1curl "http://localhost:8000/canvas/boards/example/comments"
1fetch("http://localhost:8000/canvas/boards/example/comments")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/canvas/boards/example/comments")
4print(response.json())
200 Example Response
No Body
GET /canvas/boards/:board_id/vote-sessions undocumented

/canvas/boards/:board_id/vote-sessions

GET /canvas/boards/:board_id/vote-sessions — history, newest first.

Handled by api_list_vote_sessions
Parameters
board_id string · path
required
Responses
200Successful Response
GET /canvas/boards/example/vote-sessions
1curl "http://localhost:8000/canvas/boards/example/vote-sessions"
1fetch("http://localhost:8000/canvas/boards/example/vote-sessions")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/canvas/boards/example/vote-sessions")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_get_vote_session
Parameters
board_id string · path
required
session_id string · path
required
Responses
200Successful Response
GET /canvas/boards/example/vote-sessions/example
1curl "http://localhost:8000/canvas/boards/example/vote-sessions/example"
1fetch("http://localhost:8000/canvas/boards/example/vote-sessions/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/canvas/boards/example/vote-sessions/example")
4print(response.json())
200 Example Response
No Body
PATCH /canvas/boards/:board_id

Update a board

PATCH /canvas/boards/:board_id — title, description, grid settings.

Handled by api_update_board
Parameters
board_id string · path
required
Body · UpdateBoardapplication/json
deleted
title string · min length: 1 · max length: 200
description string · max length: 2000
grid object
propertyName anything
Responses
200Successful Response
PATCH /canvas/boards/example
1curl -X PATCH "http://localhost:8000/canvas/boards/example" \
2 -H "Content-Type: application/json" \
3 -d '{"deleted":null,"title":"string","description":"string","grid":{"mode":null,"spacing":1,"snap":null,"background":"string","default_sticky_color":"string"}}'
1fetch("http://localhost:8000/canvas/boards/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "deleted": null,
6 "title": "string",
7 "description": "string",
8 "grid": {
9 "mode": null,
10 "spacing": 1,
11 "snap": null,
12 "background": "string",
13 "default_sticky_color": "string"
14 }
15}),
16})
17 .then((res) => res.json())
18 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/canvas/boards/example",
5 json={"deleted":null,"title":"string","description":"string","grid":{"mode":null,"spacing":1,"snap":null,"background":"string","default_sticky_color":"string"}},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /canvas/boards/:board_id/content

Save board content

PATCH /canvas/boards/:board_id/content — persist the (debounced) content snapshot.

Handled by api_save_content
Parameters
board_id string · path
required
Body · SaveContentapplication/json
ydoc_state string · min length: 1
required
thumbnail_key string · max length: 512
restore_snapshot_id string
asset_ids array
propertyName anything
Responses
200Successful Response
PATCH /canvas/boards/example/content
1curl -X PATCH "http://localhost:8000/canvas/boards/example/content" \
2 -H "Content-Type: application/json" \
3 -d '{"ydoc_state":"string","thumbnail_key":"string","restore_snapshot_id":"string","asset_ids":["string"]}'
1fetch("http://localhost:8000/canvas/boards/example/content", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "ydoc_state": "string",
6 "thumbnail_key": "string",
7 "restore_snapshot_id": "string",
8 "asset_ids": [
9 "string"
10 ]
11}),
12})
13 .then((res) => res.json())
14 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/canvas/boards/example/content",
5 json={"ydoc_state":"string","thumbnail_key":"string","restore_snapshot_id":"string","asset_ids":["string"]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /canvas/boards/:board_id/comments/:comment_id

Edit/resolve a comment

PATCH /canvas/boards/:board_id/comments/:comment_id — edit body (author) or resolve.

Handled by api_update_comment
Parameters
board_id string · path
required
comment_id string · path
required
Body · UpdateCommentapplication/json
body string · min length: 1 · max length: 4000
resolved
propertyName anything
Responses
200Successful Response
PATCH /canvas/boards/example/comments/example
1curl -X PATCH "http://localhost:8000/canvas/boards/example/comments/example" \
2 -H "Content-Type: application/json" \
3 -d '{"body":"string","resolved":null}'
1fetch("http://localhost:8000/canvas/boards/example/comments/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "body": "string",
6 "resolved": null
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/canvas/boards/example/comments/example",
5 json={"body":"string","resolved":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /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.

Handled by api_update_vote_session
Parameters
board_id string · path
required
session_id string · path
required
Body · UpdateVoteSessionapplication/json
status
required
object_labels array
propertyName anything
Responses
200Successful Response
PATCH /canvas/boards/example/vote-sessions/example
1curl -X PATCH "http://localhost:8000/canvas/boards/example/vote-sessions/example" \
2 -H "Content-Type: application/json" \
3 -d '{"status":null,"object_labels":[{"object_id":"string","label":"string"}]}'
1fetch("http://localhost:8000/canvas/boards/example/vote-sessions/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "status": null,
6 "object_labels": [
7 {
8 "object_id": "string",
9 "label": "string"
10 }
11 ]
12}),
13})
14 .then((res) => res.json())
15 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/canvas/boards/example/vote-sessions/example",
5 json={"status":null,"object_labels":[{"object_id":"string","label":"string"}]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /canvas/boards

Create a board

POST /canvas/boards — create a board (optionally cloned from a template).

Handled by api_create_board
Body · CreateBoardapplication/json
title string · min length: 1 · max length: 200
required
description string · max length: 2000
template_id string
is_template
grid object
propertyName anything
Responses
200Successful Response
POST /canvas/boards
1curl -X POST "http://localhost:8000/canvas/boards" \
2 -H "Content-Type: application/json" \
3 -d '{"title":"string","description":"string","template_id":"string","is_template":null,"grid":{"mode":null,"spacing":1,"snap":null,"background":"string","default_sticky_color":"string"}}'
1fetch("http://localhost:8000/canvas/boards", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "title": "string",
6 "description": "string",
7 "template_id": "string",
8 "is_template": null,
9 "grid": {
10 "mode": null,
11 "spacing": 1,
12 "snap": null,
13 "background": "string",
14 "default_sticky_color": "string"
15 }
16}),
17})
18 .then((res) => res.json())
19 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/canvas/boards",
5 json={"title":"string","description":"string","template_id":"string","is_template":null,"grid":{"mode":null,"spacing":1,"snap":null,"background":"string","default_sticky_color":"string"}},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /canvas/boards/:board_id/duplications undocumented

/canvas/boards/:board_id/duplications

POST /canvas/boards/:board_id/duplications — copy a board (or instantiate a template).

Handled by api_duplicate_board
Parameters
board_id string · path
required
Responses
200Successful Response
POST /canvas/boards/example/duplications
1curl -X POST "http://localhost:8000/canvas/boards/example/duplications"
1fetch("http://localhost:8000/canvas/boards/example/duplications", { method: "POST" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.post("http://localhost:8000/canvas/boards/example/duplications")
4print(response.json())
200 Example Response
No Body
POST /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.

Handled by api_create_asset
Parameters
board_id string · path
required
Body · CreateAssetapplication/json
asset_id string · min length: 6 · max length: 64
required
storage_key string · min length: 1 · max length: 512
required
filename string · min length: 1 · max length: 255
required
content_type string · min length: 1 · max length: 100
required
size_bytes integer · min: 0
required
width integer · min: 0
height integer · min: 0
propertyName anything
Responses
200Successful Response
POST /canvas/boards/example/assets
1curl -X POST "http://localhost:8000/canvas/boards/example/assets" \
2 -H "Content-Type: application/json" \
3 -d '{"asset_id":"string","storage_key":"string","filename":"string","content_type":"string","size_bytes":1,"width":1,"height":1}'
1fetch("http://localhost:8000/canvas/boards/example/assets", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "asset_id": "string",
6 "storage_key": "string",
7 "filename": "string",
8 "content_type": "string",
9 "size_bytes": 1,
10 "width": 1,
11 "height": 1
12}),
13})
14 .then((res) => res.json())
15 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/canvas/boards/example/assets",
5 json={"asset_id":"string","storage_key":"string","filename":"string","content_type":"string","size_bytes":1,"width":1,"height":1},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /canvas/boards/:board_id/comments

Add a comment

POST /canvas/boards/:board_id/comments — add a comment.

Handled by api_create_comment
Parameters
board_id string · path
required
Body · CreateCommentapplication/json
body string · min length: 1 · max length: 4000
required
object_id string · max length: 64
parent_id string · max length: 64
nx number
ny number
propertyName anything
Responses
200Successful Response
POST /canvas/boards/example/comments
1curl -X POST "http://localhost:8000/canvas/boards/example/comments" \
2 -H "Content-Type: application/json" \
3 -d '{"body":"string","object_id":"string","parent_id":"string","nx":1.5,"ny":1.5}'
1fetch("http://localhost:8000/canvas/boards/example/comments", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "body": "string",
6 "object_id": "string",
7 "parent_id": "string",
8 "nx": 1.5,
9 "ny": 1.5
10}),
11})
12 .then((res) => res.json())
13 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/canvas/boards/example/comments",
5 json={"body":"string","object_id":"string","parent_id":"string","nx":1.5,"ny":1.5},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /canvas/boards/:board_id/vote-sessions

Start a vote session

POST /canvas/boards/:board_id/vote-sessions — open a round of dot voting.

Handled by api_start_vote_session
Parameters
board_id string · path
required
Body · StartVoteSessionapplication/json
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
Responses
200Successful Response
POST /canvas/boards/example/vote-sessions
1curl -X POST "http://localhost:8000/canvas/boards/example/vote-sessions" \
2 -H "Content-Type: application/json" \
3 -d '{"label":"string","max_votes_per_member":1,"allow_repeat_votes":null,"scope_frame_id":"string","scope_ids":["string"]}'
1fetch("http://localhost:8000/canvas/boards/example/vote-sessions", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "label": "string",
6 "max_votes_per_member": 1,
7 "allow_repeat_votes": null,
8 "scope_frame_id": "string",
9 "scope_ids": [
10 "string"
11 ]
12}),
13})
14 .then((res) => res.json())
15 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/canvas/boards/example/vote-sessions",
5 json={"label":"string","max_votes_per_member":1,"allow_repeat_votes":null,"scope_frame_id":"string","scope_ids":["string"]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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.

Handled by api_cast_vote
Parameters
board_id string · path
required
session_id string · path
required
Body · CastVoteapplication/json
object_id string · min length: 1 · max length: 64
required
propertyName anything
Responses
200Successful Response
POST /canvas/boards/example/vote-sessions/example/votes
1curl -X POST "http://localhost:8000/canvas/boards/example/vote-sessions/example/votes" \
2 -H "Content-Type: application/json" \
3 -d '{"object_id":"string"}'
1fetch("http://localhost:8000/canvas/boards/example/vote-sessions/example/votes", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "object_id": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/canvas/boards/example/vote-sessions/example/votes",
5 json={"object_id":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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.

Handled by api_export_board
Parameters
board_id string · path
required
Body · ExportBoardapplication/json
format
required
target
data_url string · min length: 1
filename string · max length: 200
propertyName anything
Responses
200Successful Response
POST /canvas/boards/example/exports
1curl -X POST "http://localhost:8000/canvas/boards/example/exports" \
2 -H "Content-Type: application/json" \
3 -d '{"format":null,"target":null,"data_url":"string","filename":"string"}'
1fetch("http://localhost:8000/canvas/boards/example/exports", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "format": null,
6 "target": null,
7 "data_url": "string",
8 "filename": "string"
9}),
10})
11 .then((res) => res.json())
12 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/canvas/boards/example/exports",
5 json={"format":null,"target":null,"data_url":"string","filename":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /chats/:id

Update a chat

PATCH /chats/:id — update group name, description, or avatar.

Handled by api_update_chat
Parameters
id string · path
required
Body · UpdateChatapplication/json
name string · max length: 100
description string · max length: 500
avatar_key string
propertyName anything
Responses
200Successful Response
PATCH /chats/example
1curl -X PATCH "http://localhost:8000/chats/example" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","description":"string","avatar_key":"string"}'
1fetch("http://localhost:8000/chats/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "description": "string",
7 "avatar_key": "string"
8}),
9})
10 .then((res) => res.json())
11 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/chats/example",
5 json={"name":"string","description":"string","avatar_key":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /chats

Create a chat

POST /chats — create a conversation.

Handled by api_create_chat
Body · CreateChatapplication/json
type
required
name string · min length: 1 · max length: 100
description string · max length: 500
participants array
required
propertyName anything
Responses
200Successful Response
POST /chats
1curl -X POST "http://localhost:8000/chats" \
2 -H "Content-Type: application/json" \
3 -d '{"type":null,"name":"string","description":"string","participants":["string"]}'
1fetch("http://localhost:8000/chats", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "type": null,
6 "name": "string",
7 "description": "string",
8 "participants": [
9 "string"
10 ]
11}),
12})
13 .then((res) => res.json())
14 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/chats",
5 json={"type":null,"name":"string","description":"string","participants":["string"]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
DELETE /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.

Handled by api_delete_chat
Parameters
id string · path
required
Responses
200Successful Response
DELETE /chats/example
1curl -X DELETE "http://localhost:8000/chats/example"
1fetch("http://localhost:8000/chats/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/chats/example")
4print(response.json())
200 Example Response
No Body
DELETE /chats/:id/messages undocumented

/chats/:id/messages

DELETE /chats/:id/messages — clear the conversation for the caller only.

Handled by api_clear_chat
Parameters
id string · path
required
Responses
200Successful Response
DELETE /chats/example/messages
1curl -X DELETE "http://localhost:8000/chats/example/messages"
1fetch("http://localhost:8000/chats/example/messages", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/chats/example/messages")
4print(response.json())
200 Example Response
No Body
DELETE /chats/:id/messages/:msg_id undocumented

/chats/:id/messages/:msg_id

DELETE /chats/:id/messages/:msg_id — soft-delete a message.

Handled by api_delete_message
Parameters
id string · path
required
msg_id string · path
required
Responses
200Successful Response
DELETE /chats/example/messages/example
1curl -X DELETE "http://localhost:8000/chats/example/messages/example"
1fetch("http://localhost:8000/chats/example/messages/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/chats/example/messages/example")
4print(response.json())
200 Example Response
No Body
DELETE /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.

Handled by api_remove_reaction
Parameters
id string · path
required
msg_id string · path
required
emoji string · path
required
Responses
200Successful Response
DELETE /chats/example/messages/example/reactions/example
1curl -X DELETE "http://localhost:8000/chats/example/messages/example/reactions/example"
1fetch("http://localhost:8000/chats/example/messages/example/reactions/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/chats/example/messages/example/reactions/example")
4print(response.json())
200 Example Response
No Body
DELETE /chats/:id/participants/:member_mrn undocumented

/chats/:id/participants/:member_mrn

DELETE /chats/:id/participants/:member_mrn — remove from a group, or leave.

Handled by api_remove_participant
Parameters
id string · path
required
member_mrn string · path
required
Responses
200Successful Response
DELETE /chats/example/participants/example
1curl -X DELETE "http://localhost:8000/chats/example/participants/example"
1fetch("http://localhost:8000/chats/example/participants/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/chats/example/participants/example")
4print(response.json())
200 Example Response
No Body
DELETE /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.

Handled by api_delete_chat_list
Parameters
list_id string · path
required
Responses
200Successful Response
DELETE /chats/lists/example
1curl -X DELETE "http://localhost:8000/chats/lists/example"
1fetch("http://localhost:8000/chats/lists/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/chats/lists/example")
4print(response.json())
200 Example Response
No Body
DELETE /chats/:id/favourite undocumented

/chats/:id/favourite

DELETE /chats/:id/favourite — remove the favourite mark (per-user).

Handled by api_unfavourite_chat
Parameters
id string · path
required
Responses
200Successful Response
DELETE /chats/example/favourite
1curl -X DELETE "http://localhost:8000/chats/example/favourite"
1fetch("http://localhost:8000/chats/example/favourite", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/chats/example/favourite")
4print(response.json())
200 Example Response
No Body
DELETE /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.

Handled by api_remove_chat_from_list
Parameters
id string · path
required
list_id string · path
required
Responses
200Successful Response
DELETE /chats/example/lists/example
1curl -X DELETE "http://localhost:8000/chats/example/lists/example"
1fetch("http://localhost:8000/chats/example/lists/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/chats/example/lists/example")
4print(response.json())
200 Example Response
No Body
GET /chats undocumented

/chats

GET /chats — the caller's conversations, newest first.

Handled by api_list_chats
Responses
200Successful Response
GET /chats
1curl "http://localhost:8000/chats"
1fetch("http://localhost:8000/chats")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/chats")
4print(response.json())
200 Example Response
No Body
GET /chats/:id undocumented

/chats/:id

GET /chats/:id — conversation details.

Handled by api_get_chat
Parameters
id string · path
required
Responses
200Successful Response
GET /chats/example
1curl "http://localhost:8000/chats/example"
1fetch("http://localhost:8000/chats/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/chats/example")
4print(response.json())
200 Example Response
No Body
GET /chats/:id/messages undocumented

/chats/:id/messages

GET /chats/:id/messages — messages in a conversation.

Handled by api_list_messages
Parameters
id string · path
required
Responses
200Successful Response
GET /chats/example/messages
1curl "http://localhost:8000/chats/example/messages"
1fetch("http://localhost:8000/chats/example/messages")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/chats/example/messages")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_message_receipts
Parameters
id string · path
required
msg_id string · path
required
Responses
200Successful Response
GET /chats/example/messages/example/receipts
1curl "http://localhost:8000/chats/example/messages/example/receipts"
1fetch("http://localhost:8000/chats/example/messages/example/receipts")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/chats/example/messages/example/receipts")
4print(response.json())
200 Example Response
No Body
GET /chats/:id/participants undocumented

/chats/:id/participants

GET /chats/:id/participants — list participants.

Handled by api_list_participants
Parameters
id string · path
required
Responses
200Successful Response
GET /chats/example/participants
1curl "http://localhost:8000/chats/example/participants"
1fetch("http://localhost:8000/chats/example/participants")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/chats/example/participants")
4print(response.json())
200 Example Response
No Body
GET /chats/lists undocumented

/chats/lists

GET /chats/lists — the caller's personal chat lists, ordered.

Handled by api_list_chat_lists
Responses
200Successful Response
GET /chats/lists
1curl "http://localhost:8000/chats/lists"
1fetch("http://localhost:8000/chats/lists")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/chats/lists")
4print(response.json())
200 Example Response
No Body
PUT /chats/:id/read undocumented

/chats/:id/read

PUT /chats/:id/read — mark a conversation as read.

Handled by api_mark_read
Parameters
id string · path
required
Responses
200Successful Response
PUT /chats/example/read
1curl -X PUT "http://localhost:8000/chats/example/read"
1fetch("http://localhost:8000/chats/example/read", { method: "PUT" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.put("http://localhost:8000/chats/example/read")
4print(response.json())
200 Example Response
No Body
PUT /chats/:id/favourite undocumented

/chats/:id/favourite

PUT /chats/:id/favourite — mark the chat as a favourite (per-user).

Handled by api_favourite_chat
Parameters
id string · path
required
Responses
200Successful Response
PUT /chats/example/favourite
1curl -X PUT "http://localhost:8000/chats/example/favourite"
1fetch("http://localhost:8000/chats/example/favourite", { method: "PUT" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.put("http://localhost:8000/chats/example/favourite")
4print(response.json())
200 Example Response
No Body
PUT /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.

Handled by api_add_chat_to_list
Parameters
id string · path
required
list_id string · path
required
Responses
200Successful Response
PUT /chats/example/lists/example
1curl -X PUT "http://localhost:8000/chats/example/lists/example"
1fetch("http://localhost:8000/chats/example/lists/example", { method: "PUT" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.put("http://localhost:8000/chats/example/lists/example")
4print(response.json())
200 Example Response
No Body
PATCH /checklists/:checklist_id/workers/:worker_id/items/:item_id

Toggle an assignment item

Handled by api_toggle_assignment_item
Parameters
checklist_id string · path
required
worker_id string · path
required
item_id string · path
required
Body · UpdateAssignmentItemapplication/json
completed
required
propertyName anything
Responses
200Successful Response
PATCH /checklists/example/workers/example/items/example
1curl -X PATCH "http://localhost:8000/checklists/example/workers/example/items/example" \
2 -H "Content-Type: application/json" \
3 -d '{"completed":null}'
1fetch("http://localhost:8000/checklists/example/workers/example/items/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "completed": null
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/checklists/example/workers/example/items/example",
5 json={"completed":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /checklists/:checklist_id/workers

Assign a checklist to a worker

Handled by api_assign_checklist
Parameters
checklist_id string · path
required
Body · AssignChecklistapplication/json
worker_id string · min length: 1
required
due_date string
anchor_date string · max length: 10
responsible_worker_id string
propertyName anything
Responses
200Successful Response
POST /checklists/example/workers
1curl -X POST "http://localhost:8000/checklists/example/workers" \
2 -H "Content-Type: application/json" \
3 -d '{"worker_id":"string","due_date":"string","anchor_date":"string","responsible_worker_id":"string"}'
1fetch("http://localhost:8000/checklists/example/workers", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "worker_id": "string",
6 "due_date": "string",
7 "anchor_date": "string",
8 "responsible_worker_id": "string"
9}),
10})
11 .then((res) => res.json())
12 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/checklists/example/workers",
5 json={"worker_id":"string","due_date":"string","anchor_date":"string","responsible_worker_id":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /checklists/:checklist_id/workers/:worker_id

Update assignment status

Handled by api_update_assignment
Parameters
checklist_id string · path
required
worker_id string · path
required
Body · UpdateAssignmentapplication/json
status
due_date string
anchor_date string · max length: 10
responsible_worker_id string
propertyName anything
Responses
200Successful Response
PUT /checklists/example/workers/example
1curl -X PUT "http://localhost:8000/checklists/example/workers/example" \
2 -H "Content-Type: application/json" \
3 -d '{"status":null,"due_date":"string","anchor_date":"string","responsible_worker_id":"string"}'
1fetch("http://localhost:8000/checklists/example/workers/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "status": null,
6 "due_date": "string",
7 "anchor_date": "string",
8 "responsible_worker_id": "string"
9}),
10})
11 .then((res) => res.json())
12 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/checklists/example/workers/example",
5 json={"status":null,"due_date":"string","anchor_date":"string","responsible_worker_id":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
DELETE /checklists/:checklist_id undocumented

/checklists/:checklist_id

Handled by api_delete_checklist
Parameters
checklist_id string · path
required
Responses
200Successful Response
DELETE /checklists/example
1curl -X DELETE "http://localhost:8000/checklists/example"
1fetch("http://localhost:8000/checklists/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/checklists/example")
4print(response.json())
200 Example Response
No Body
DELETE /checklists/:checklist_id/workers/:worker_id undocumented

/checklists/:checklist_id/workers/:worker_id

Handled by api_delete_assignment
Parameters
checklist_id string · path
required
worker_id string · path
required
Responses
200Successful Response
DELETE /checklists/example/workers/example
1curl -X DELETE "http://localhost:8000/checklists/example/workers/example"
1fetch("http://localhost:8000/checklists/example/workers/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/checklists/example/workers/example")
4print(response.json())
200 Example Response
No Body
GET /checklists undocumented

/checklists

Handled by api_list_checklists
Responses
200Successful Response
GET /checklists
1curl "http://localhost:8000/checklists"
1fetch("http://localhost:8000/checklists")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/checklists")
4print(response.json())
200 Example Response
No Body
GET /checklists/:checklist_id undocumented

/checklists/:checklist_id

Handled by api_get_checklist
Parameters
checklist_id string · path
required
Responses
200Successful Response
GET /checklists/example
1curl "http://localhost:8000/checklists/example"
1fetch("http://localhost:8000/checklists/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/checklists/example")
4print(response.json())
200 Example Response
No Body
GET /checklists/:checklist_id/workers undocumented

/checklists/:checklist_id/workers

Handled by api_list_assignments
Parameters
checklist_id string · path
required
Responses
200Successful Response
GET /checklists/example/workers
1curl "http://localhost:8000/checklists/example/workers"
1fetch("http://localhost:8000/checklists/example/workers")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/checklists/example/workers")
4print(response.json())
200 Example Response
No Body
POST /checklists

Create a checklist template

Handled by api_create_checklist
Body · CreateChecklistapplication/json
type
required
title string · min length: 1 · max length: 200
required
items array
auto_assign object
propertyName anything
Responses
200Successful Response
POST /checklists
1curl -X POST "http://localhost:8000/checklists" \
2 -H "Content-Type: application/json" \
3 -d '{"type":null,"title":"string","items":[{"name":"string","id":"string","description":"string","link":"string","owner_kind":null,"owner_worker_id":"string","due_offset_days":1}],"auto_assign":{"enabled":null,"trigger":null,"department_ids":["string"]}}'
1fetch("http://localhost:8000/checklists", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "type": null,
6 "title": "string",
7 "items": [
8 {
9 "name": "string",
10 "id": "string",
11 "description": "string",
12 "link": "string",
13 "owner_kind": null,
14 "owner_worker_id": "string",
15 "due_offset_days": 1
16 }
17 ],
18 "auto_assign": {
19 "enabled": null,
20 "trigger": null,
21 "department_ids": [
22 "string"
23 ]
24 }
25}),
26})
27 .then((res) => res.json())
28 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/checklists",
5 json={"type":null,"title":"string","items":[{"name":"string","id":"string","description":"string","link":"string","owner_kind":null,"owner_worker_id":"string","due_offset_days":1}],"auto_assign":{"enabled":null,"trigger":null,"department_ids":["string"]}},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /checklists/:checklist_id

Update a checklist template

Handled by api_update_checklist
Parameters
checklist_id string · path
required
Body · UpdateChecklistapplication/json
title string · min length: 1 · max length: 200
type
items array
auto_assign object
propertyName anything
Responses
200Successful Response
PUT /checklists/example
1curl -X PUT "http://localhost:8000/checklists/example" \
2 -H "Content-Type: application/json" \
3 -d '{"title":"string","type":null,"items":[{"name":"string","id":"string","description":"string","link":"string","owner_kind":null,"owner_worker_id":"string","due_offset_days":1}],"auto_assign":{"enabled":null,"trigger":null,"department_ids":["string"]}}'
1fetch("http://localhost:8000/checklists/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "title": "string",
6 "type": null,
7 "items": [
8 {
9 "name": "string",
10 "id": "string",
11 "description": "string",
12 "link": "string",
13 "owner_kind": null,
14 "owner_worker_id": "string",
15 "due_offset_days": 1
16 }
17 ],
18 "auto_assign": {
19 "enabled": null,
20 "trigger": null,
21 "department_ids": [
22 "string"
23 ]
24 }
25}),
26})
27 .then((res) => res.json())
28 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/checklists/example",
5 json={"title":"string","type":null,"items":[{"name":"string","id":"string","description":"string","link":"string","owner_kind":null,"owner_worker_id":"string","due_offset_days":1}],"auto_assign":{"enabled":null,"trigger":null,"department_ids":["string"]}},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
DELETE /companies/:company_id undocumented

/companies/:company_id

DELETE /companies/:company_id — delete company (fails if contacts still linked).

Handled by api_delete_company
Parameters
company_id string · path
required
Responses
200Successful Response
DELETE /companies/example
1curl -X DELETE "http://localhost:8000/companies/example"
1fetch("http://localhost:8000/companies/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/companies/example")
4print(response.json())
200 Example Response
No Body
GET /companies undocumented

/companies

GET /companies — list companies with filters.

Handled by api_list_companies
Responses
200Successful Response
GET /companies
1curl "http://localhost:8000/companies"
1fetch("http://localhost:8000/companies")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/companies")
4print(response.json())
200 Example Response
No Body
GET /companies/:company_id undocumented

/companies/:company_id

GET /companies/:company_id — get company with contacts and recent interactions.

Handled by api_get_company
Parameters
company_id string · path
required
Responses
200Successful Response
GET /companies/example
1curl "http://localhost:8000/companies/example"
1fetch("http://localhost:8000/companies/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/companies/example")
4print(response.json())
200 Example Response
No Body
GET /companies/:company_id/interactions undocumented

/companies/:company_id/interactions

GET /companies/:company_id/interactions — interactions for a company (across all contacts).

Handled by api_list_company_interactions
Parameters
company_id string · path
required
Responses
200Successful Response
GET /companies/example/interactions
1curl "http://localhost:8000/companies/example/interactions"
1fetch("http://localhost:8000/companies/example/interactions")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/companies/example/interactions")
4print(response.json())
200 Example Response
No Body
POST /companies

Create a company

POST /companies — create a company.

Handled by api_create_company
Body · CreateCompanyapplication/json
name string · min length: 1 · max length: 200
required
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
Responses
200Successful Response
POST /companies
1curl -X POST "http://localhost:8000/companies" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","domain":"string","industry":"string","size":null,"address":"string","phone":"string","annual_revenue":"string","tags":["string"],"relationships":["string"],"owner_mrn":"string","notes":"string","contact_name":"string","contact_email":"string","contact_title":"string","contact_source":null}'
1fetch("http://localhost:8000/companies", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "domain": "string",
7 "industry": "string",
8 "size": null,
9 "address": "string",
10 "phone": "string",
11 "annual_revenue": "string",
12 "tags": [
13 "string"
14 ],
15 "relationships": [
16 "string"
17 ],
18 "owner_mrn": "string",
19 "notes": "string",
20 "contact_name": "string",
21 "contact_email": "string",
22 "contact_title": "string",
23 "contact_source": null
24}),
25})
26 .then((res) => res.json())
27 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/companies",
5 json={"name":"string","domain":"string","industry":"string","size":null,"address":"string","phone":"string","annual_revenue":"string","tags":["string"],"relationships":["string"],"owner_mrn":"string","notes":"string","contact_name":"string","contact_email":"string","contact_title":"string","contact_source":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /companies/:company_id

Update a company

PUT /companies/:company_id — update a company.

Handled by api_update_company
Parameters
company_id string · path
required
Body · UpdateCompanyapplication/json
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
Responses
200Successful Response
PUT /companies/example
1curl -X PUT "http://localhost:8000/companies/example" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","domain":"string","industry":"string","size":null,"address":"string","phone":"string","annual_revenue":"string","tags":["string"],"relationships":["string"],"archived":null,"owner_mrn":"string","notes":"string"}'
1fetch("http://localhost:8000/companies/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "domain": "string",
7 "industry": "string",
8 "size": null,
9 "address": "string",
10 "phone": "string",
11 "annual_revenue": "string",
12 "tags": [
13 "string"
14 ],
15 "relationships": [
16 "string"
17 ],
18 "archived": null,
19 "owner_mrn": "string",
20 "notes": "string"
21}),
22})
23 .then((res) => res.json())
24 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/companies/example",
5 json={"name":"string","domain":"string","industry":"string","size":null,"address":"string","phone":"string","annual_revenue":"string","tags":["string"],"relationships":["string"],"archived":null,"owner_mrn":"string","notes":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
DELETE /compensation/:compensation_id undocumented

/compensation/:compensation_id

Handled by api_delete_compensation
Parameters
compensation_id string · path
required
Responses
200Successful Response
DELETE /compensation/example
1curl -X DELETE "http://localhost:8000/compensation/example"
1fetch("http://localhost:8000/compensation/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/compensation/example")
4print(response.json())
200 Example Response
No Body
GET /compensation undocumented

/compensation

All workers with their latest compensation record.

Handled by api_list_all_compensation
Responses
200Successful Response
GET /compensation
1curl "http://localhost:8000/compensation"
1fetch("http://localhost:8000/compensation")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/compensation")
4print(response.json())
200 Example Response
No Body
GET /compensation/changes undocumented

/compensation/changes

Recent compensation changes across all workers.

Handled by api_list_compensation_changes
Responses
200Successful Response
GET /compensation/changes
1curl "http://localhost:8000/compensation/changes"
1fetch("http://localhost:8000/compensation/changes")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/compensation/changes")
4print(response.json())
200 Example Response
No Body
POST /workers/:worker_id/compensation

Add compensation record

Handled by api_create_compensation
Parameters
worker_id string · path
required
Body · CreateCompensationapplication/json
effective_date string · min length: 1
required
items array
required
reason string · max length: 500
notes string · max length: 2000
propertyName anything
Responses
200Successful Response
POST /workers/example/compensation
1curl -X POST "http://localhost:8000/workers/example/compensation" \
2 -H "Content-Type: application/json" \
3 -d '{"effective_date":"string","items":[{"type":"string","label":"string","amount":1.5,"currency":"string","frequency":null}],"reason":"string","notes":"string"}'
1fetch("http://localhost:8000/workers/example/compensation", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "effective_date": "string",
6 "items": [
7 {
8 "type": "string",
9 "label": "string",
10 "amount": 1.5,
11 "currency": "string",
12 "frequency": null
13 }
14 ],
15 "reason": "string",
16 "notes": "string"
17}),
18})
19 .then((res) => res.json())
20 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/workers/example/compensation",
5 json={"effective_date":"string","items":[{"type":"string","label":"string","amount":1.5,"currency":"string","frequency":null}],"reason":"string","notes":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
DELETE /contacts/suggestions/:suggestion_id undocumented

/contacts/suggestions/:suggestion_id

DELETE /contacts/suggestions/:suggestion_id — drop a suggestion outright.

Handled by api_delete_suggestion
Parameters
suggestion_id string · path
required
Responses
200Successful Response
DELETE /contacts/suggestions/example
1curl -X DELETE "http://localhost:8000/contacts/suggestions/example"
1fetch("http://localhost:8000/contacts/suggestions/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/contacts/suggestions/example")
4print(response.json())
200 Example Response
No Body
DELETE /contacts/relationships/:key undocumented

/contacts/relationships/:key

DELETE /contacts/relationships/:key: remove a workspace value from the list and from every record.

Handled by api_delete_relationship
Parameters
key string · path
required
Responses
200Successful Response
DELETE /contacts/relationships/example
1curl -X DELETE "http://localhost:8000/contacts/relationships/example"
1fetch("http://localhost:8000/contacts/relationships/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/contacts/relationships/example")
4print(response.json())
200 Example Response
No Body
DELETE /contacts/:contact_id undocumented

/contacts/:contact_id

DELETE /contacts/:contact_id — delete a contact with soft warning if MRN-referenced.

Handled by api_delete_contact
Parameters
contact_id string · path
required
Responses
200Successful Response
DELETE /contacts/example
1curl -X DELETE "http://localhost:8000/contacts/example"
1fetch("http://localhost:8000/contacts/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/contacts/example")
4print(response.json())
200 Example Response
No Body
GET /contacts undocumented

/contacts

GET /contacts — list contacts with filters.

Handled by api_list_contacts
Responses
200Successful Response
GET /contacts
1curl "http://localhost:8000/contacts"
1fetch("http://localhost:8000/contacts")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/contacts")
4print(response.json())
200 Example Response
No Body
GET /contacts/search undocumented

/contacts/search

GET /contacts/search: unified search across contacts and companies, best match first.

Handled by api_search
Responses
200Successful Response
GET /contacts/search
1curl "http://localhost:8000/contacts/search"
1fetch("http://localhost:8000/contacts/search")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/contacts/search")
4print(response.json())
200 Example Response
No Body
GET /contacts/suggestions undocumented

/contacts/suggestions

GET /contacts/suggestions — the pending review queue, most active first.

Handled by api_list_suggestions
Responses
200Successful Response
GET /contacts/suggestions
1curl "http://localhost:8000/contacts/suggestions"
1fetch("http://localhost:8000/contacts/suggestions")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/contacts/suggestions")
4print(response.json())
200 Example Response
No Body
GET /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).

Handled by api_dashboard
Responses
200Successful Response
GET /contacts/dashboard
1curl "http://localhost:8000/contacts/dashboard"
1fetch("http://localhost:8000/contacts/dashboard")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/contacts/dashboard")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_export_contacts
Responses
200Successful Response
GET /contacts/exports
1curl "http://localhost:8000/contacts/exports"
1fetch("http://localhost:8000/contacts/exports")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/contacts/exports")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_list_duplicates
Responses
200Successful Response
GET /contacts/duplicates
1curl "http://localhost:8000/contacts/duplicates"
1fetch("http://localhost:8000/contacts/duplicates")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/contacts/duplicates")
4print(response.json())
200 Example Response
No Body
GET /contacts/settings undocumented

/contacts/settings

GET /contacts/settings — named embed configurations and snippets.

Handled by api_get_settings
Responses
200Successful Response
GET /contacts/settings
1curl "http://localhost:8000/contacts/settings"
1fetch("http://localhost:8000/contacts/settings")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/contacts/settings")
4print(response.json())
200 Example Response
No Body
GET /contacts/relationships undocumented

/contacts/relationships

GET /contacts/relationships: the built-in values first, then the workspace's own.

Handled by api_list_relationships
Responses
200Successful Response
GET /contacts/relationships
1curl "http://localhost:8000/contacts/relationships"
1fetch("http://localhost:8000/contacts/relationships")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/contacts/relationships")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_get_support_settings
Responses
200Successful Response
GET /contacts/support/settings
1curl "http://localhost:8000/contacts/support/settings"
1fetch("http://localhost:8000/contacts/support/settings")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/contacts/support/settings")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_list_support_mailboxes
Responses
200Successful Response
GET /contacts/support/mailboxes
1curl "http://localhost:8000/contacts/support/mailboxes"
1fetch("http://localhost:8000/contacts/support/mailboxes")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/contacts/support/mailboxes")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_get_support_confirmation
Parameters
confirmation_id string · path
required
Responses
200Successful Response
GET /contacts/support/confirmations/example
1curl "http://localhost:8000/contacts/support/confirmations/example"
1fetch("http://localhost:8000/contacts/support/confirmations/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/contacts/support/confirmations/example")
4print(response.json())
200 Example Response
No Body
GET /contacts/:contact_id undocumented

/contacts/:contact_id

GET /contacts/:contact_id — get contact with company info and recent interactions.

Handled by api_get_contact
Parameters
contact_id string · path
required
Responses
200Successful Response
GET /contacts/example
1curl "http://localhost:8000/contacts/example"
1fetch("http://localhost:8000/contacts/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/contacts/example")
4print(response.json())
200 Example Response
No Body
GET /contacts/:contact_id/interactions undocumented

/contacts/:contact_id/interactions

GET /contacts/:contact_id/interactions — interactions for a contact.

Handled by api_list_contact_interactions
Parameters
contact_id string · path
required
Responses
200Successful Response
GET /contacts/example/interactions
1curl "http://localhost:8000/contacts/example/interactions"
1fetch("http://localhost:8000/contacts/example/interactions")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/contacts/example/interactions")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_reports
Responses
200Successful Response
GET /contacts/reports
1curl "http://localhost:8000/contacts/reports"
1fetch("http://localhost:8000/contacts/reports")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/contacts/reports")
4print(response.json())
200 Example Response
No Body
PATCH /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.

Handled by api_update_suggestion
Parameters
suggestion_id string · path
required
Body · UpdateSuggestionapplication/json
status
required
name string · min length: 1 · max length: 200
company_id string
propertyName anything
Responses
200Successful Response
PATCH /contacts/suggestions/example
1curl -X PATCH "http://localhost:8000/contacts/suggestions/example" \
2 -H "Content-Type: application/json" \
3 -d '{"status":null,"name":"string","company_id":"string"}'
1fetch("http://localhost:8000/contacts/suggestions/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "status": null,
6 "name": "string",
7 "company_id": "string"
8}),
9})
10 .then((res) => res.json())
11 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/contacts/suggestions/example",
5 json={"status":null,"name":"string","company_id":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /contacts

Create a contact

POST /contacts — create a contact with domain extraction and auto company linking.

Handled by api_create_contact
Body · CreateContactapplication/json
name string · min length: 1 · max length: 200
required
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
Responses
200Successful Response
POST /contacts
1curl -X POST "http://localhost:8000/contacts" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","email":"string","phone":"string","mobile":"string","secondary_email":"string","title":"string","department":"string","company_id":"string","linkedin_url":"string","website":"string","social_url":"string","address":"string","tags":["string"],"role":"string","lifecycle_stage":null,"preferred_channel":null,"timezone":"string","birthday":"string","avatar_url":"string","notes":"string","custom_fields":[{"key":"string","value":"string"}],"relationships":["string"],"owner_mrn":"string","source":null}'
1fetch("http://localhost:8000/contacts", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "email": "string",
7 "phone": "string",
8 "mobile": "string",
9 "secondary_email": "string",
10 "title": "string",
11 "department": "string",
12 "company_id": "string",
13 "linkedin_url": "string",
14 "website": "string",
15 "social_url": "string",
16 "address": "string",
17 "tags": [
18 "string"
19 ],
20 "role": "string",
21 "lifecycle_stage": null,
22 "preferred_channel": null,
23 "timezone": "string",
24 "birthday": "string",
25 "avatar_url": "string",
26 "notes": "string",
27 "custom_fields": [
28 {
29 "key": "string",
30 "value": "string"
31 }
32 ],
33 "relationships": [
34 "string"
35 ],
36 "owner_mrn": "string",
37 "source": null
38}),
39})
40 .then((res) => res.json())
41 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/contacts",
5 json={"name":"string","email":"string","phone":"string","mobile":"string","secondary_email":"string","title":"string","department":"string","company_id":"string","linkedin_url":"string","website":"string","social_url":"string","address":"string","tags":["string"],"role":"string","lifecycle_stage":null,"preferred_channel":null,"timezone":"string","birthday":"string","avatar_url":"string","notes":"string","custom_fields":[{"key":"string","value":"string"}],"relationships":["string"],"owner_mrn":"string","source":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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.

Handled by api_import_contacts
Body · ImportContactsapplication/json
csv string · min length: 1 · max length: 2000000
required
mappings array
required
has_header
company_id string
propertyName anything
Responses
200Successful Response
POST /contacts/imports
1curl -X POST "http://localhost:8000/contacts/imports" \
2 -H "Content-Type: application/json" \
3 -d '{"csv":"string","mappings":[{"column":"string","field":"string"}],"has_header":null,"company_id":"string"}'
1fetch("http://localhost:8000/contacts/imports", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "csv": "string",
6 "mappings": [
7 {
8 "column": "string",
9 "field": "string"
10 }
11 ],
12 "has_header": null,
13 "company_id": "string"
14}),
15})
16 .then((res) => res.json())
17 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/contacts/imports",
5 json={"csv":"string","mappings":[{"column":"string","field":"string"}],"has_header":null,"company_id":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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``.

Handled by api_rotate_widget_key
Responses
200Successful Response
POST /contacts/settings/widget-keys
1curl -X POST "http://localhost:8000/contacts/settings/widget-keys"
1fetch("http://localhost:8000/contacts/settings/widget-keys", { method: "POST" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.post("http://localhost:8000/contacts/settings/widget-keys")
4print(response.json())
200 Example Response
No Body
POST /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.

Handled by api_rotate_embed_key
Parameters
embed_id string · path
required
Responses
200Successful Response
POST /contacts/settings/embeds/example/rotate-key
1curl -X POST "http://localhost:8000/contacts/settings/embeds/example/rotate-key"
1fetch("http://localhost:8000/contacts/settings/embeds/example/rotate-key", { method: "POST" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.post("http://localhost:8000/contacts/settings/embeds/example/rotate-key")
4print(response.json())
200 Example Response
No Body
POST /contacts/relationships

Add a relationship value

POST /contacts/relationships: add a relationship value of the workspace's own.

Handled by api_create_relationship
Body · CreateRelationshipapplication/json
label string · min length: 1 · max length: 40
required
propertyName anything
Responses
200Successful Response
POST /contacts/relationships
1curl -X POST "http://localhost:8000/contacts/relationships" \
2 -H "Content-Type: application/json" \
3 -d '{"label":"string"}'
1fetch("http://localhost:8000/contacts/relationships", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "label": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/contacts/relationships",
5 json={"label":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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.

Handled by api_merge_contacts
Parameters
contact_id string · path
required
Body · MergeContactsapplication/json
duplicate_id string · min length: 1
required
propertyName anything
Responses
200Successful Response
POST /contacts/example/merges
1curl -X POST "http://localhost:8000/contacts/example/merges" \
2 -H "Content-Type: application/json" \
3 -d '{"duplicate_id":"string"}'
1fetch("http://localhost:8000/contacts/example/merges", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "duplicate_id": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/contacts/example/merges",
5 json={"duplicate_id":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /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.

Handled by api_update_settings
Body · UpdateContactsSettingsapplication/json
embeds array
widget object
dormant_after_days integer · min: 1 · max: 3650
propertyName anything
Responses
200Successful Response
PUT /contacts/settings
1curl -X PUT "http://localhost:8000/contacts/settings" \
2 -H "Content-Type: application/json" \
3 -d '{"embeds":[{"id":"string","name":"string","enabled":null,"allowed_origins":["string"],"greeting":"string","subtitle":"string","color":"string","position":null,"allow_uploads":null,"fields":{"name":null,"email":null,"phone":null}}],"widget":{"enabled":null,"allowed_origins":["string"],"greeting":"string","subtitle":"string","color":"string","position":null,"allow_uploads":null,"fields":{"name":null,"email":null,"phone":null}},"dormant_after_days":1}'
1fetch("http://localhost:8000/contacts/settings", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "embeds": [
6 {
7 "id": "string",
8 "name": "string",
9 "enabled": null,
10 "allowed_origins": [
11 "string"
12 ],
13 "greeting": "string",
14 "subtitle": "string",
15 "color": "string",
16 "position": null,
17 "allow_uploads": null,
18 "fields": {
19 "name": null,
20 "email": null,
21 "phone": null
22 }
23 }
24 ],
25 "widget": {
26 "enabled": null,
27 "allowed_origins": [
28 "string"
29 ],
30 "greeting": "string",
31 "subtitle": "string",
32 "color": "string",
33 "position": null,
34 "allow_uploads": null,
35 "fields": {
36 "name": null,
37 "email": null,
38 "phone": null
39 }
40 },
41 "dormant_after_days": 1
42}),
43})
44 .then((res) => res.json())
45 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/contacts/settings",
5 json={"embeds":[{"id":"string","name":"string","enabled":null,"allowed_origins":["string"],"greeting":"string","subtitle":"string","color":"string","position":null,"allow_uploads":null,"fields":{"name":null,"email":null,"phone":null}}],"widget":{"enabled":null,"allowed_origins":["string"],"greeting":"string","subtitle":"string","color":"string","position":null,"allow_uploads":null,"fields":{"name":null,"email":null,"phone":null}},"dormant_after_days":1},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /contacts/:contact_id

Update a contact

PUT /contacts/:contact_id — update a contact.

Handled by api_update_contact
Parameters
contact_id string · path
required
Body · UpdateContactapplication/json
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
Responses
200Successful Response
PUT /contacts/example
1curl -X PUT "http://localhost:8000/contacts/example" \
2 -H "Content-Type: application/json" \
3 -d '{"phone_number":"string","street":"string","city":"string","state":"string","postal_code":"string","country":"string"}'
1fetch("http://localhost:8000/contacts/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "phone_number": "string",
6 "street": "string",
7 "city": "string",
8 "state": "string",
9 "postal_code": "string",
10 "country": "string"
11}),
12})
13 .then((res) => res.json())
14 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/contacts/example",
5 json={"phone_number":"string","street":"string","city":"string","state":"string","postal_code":"string","country":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /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.

Handled by api_set_contact_state
Parameters
contact_id string · path
required
Body · SetContactStateapplication/json
state
required
reason string · max length: 200
propertyName anything
Responses
200Successful Response
PUT /contacts/example/state
1curl -X PUT "http://localhost:8000/contacts/example/state" \
2 -H "Content-Type: application/json" \
3 -d '{"state":null,"reason":"string"}'
1fetch("http://localhost:8000/contacts/example/state", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "state": null,
6 "reason": "string"
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/contacts/example/state",
5 json={"state":null,"reason":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
GET /conversations undocumented

/conversations

GET /conversations: the ticket list. Filters: status, status_key, type_key, assignee_mrn, priority, contact_id, channel, overdue, q.

Handled by api_list_conversations
Responses
200Successful Response
GET /conversations
1curl "http://localhost:8000/conversations"
1fetch("http://localhost:8000/conversations")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/conversations")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_get_conversation
Parameters
conversation_id string · path
required
Responses
200Successful Response
GET /conversations/example
1curl "http://localhost:8000/conversations/example"
1fetch("http://localhost:8000/conversations/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/conversations/example")
4print(response.json())
200 Example Response
No Body
PATCH /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.

Handled by api_update_conversation
Parameters
conversation_id string · path
required
Body · UpdateConversationapplication/json
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
Responses
200Successful Response
PATCH /conversations/example
1curl -X PATCH "http://localhost:8000/conversations/example" \
2 -H "Content-Type: application/json" \
3 -d '{"status":null,"status_key":"string","type_key":"string","priority":null,"assignee_mrn":"string","tags":["string"],"contact_id":"string"}'
1fetch("http://localhost:8000/conversations/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "status": null,
6 "status_key": "string",
7 "type_key": "string",
8 "priority": null,
9 "assignee_mrn": "string",
10 "tags": [
11 "string"
12 ],
13 "contact_id": "string"
14}),
15})
16 .then((res) => res.json())
17 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/conversations/example",
5 json={"status":null,"status_key":"string","type_key":"string","priority":null,"assignee_mrn":"string","tags":["string"],"contact_id":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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.

Handled by api_start_support_confirmation
Body · StartSupportConfirmationapplication/json
mailbox_id string · min length: 1 · max length: 80
required
propertyName anything
Responses
200Successful Response
POST /contacts/support/confirmations
1curl -X POST "http://localhost:8000/contacts/support/confirmations" \
2 -H "Content-Type: application/json" \
3 -d '{"mailbox_id":"string"}'
1fetch("http://localhost:8000/contacts/support/confirmations", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "mailbox_id": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/contacts/support/confirmations",
5 json={"mailbox_id":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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.

Handled by api_create_conversation
Body · CreateConversationapplication/json
contact_id string · min length: 1 · max length: 60
required
subject string · min length: 1 · max length: 200
required
body string · min length: 1 · max length: 10000
required
priority
type_key string · max length: 40
assignee_mrn string · max length: 200
propertyName anything
Responses
200Successful Response
POST /conversations
1curl -X POST "http://localhost:8000/conversations" \
2 -H "Content-Type: application/json" \
3 -d '{"contact_id":"string","subject":"string","body":"string","priority":null,"type_key":"string","assignee_mrn":"string"}'
1fetch("http://localhost:8000/conversations", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "contact_id": "string",
6 "subject": "string",
7 "body": "string",
8 "priority": null,
9 "type_key": "string",
10 "assignee_mrn": "string"
11}),
12})
13 .then((res) => res.json())
14 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/conversations",
5 json={"contact_id":"string","subject":"string","body":"string","priority":null,"type_key":"string","assignee_mrn":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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.

Handled by api_create_conversation_message
Parameters
conversation_id string · path
required
Body · CreateConversationMessageapplication/json
body string · min length: 1 · max length: 10000
required
is_internal
propertyName anything
Responses
200Successful Response
POST /conversations/example/messages
1curl -X POST "http://localhost:8000/conversations/example/messages" \
2 -H "Content-Type: application/json" \
3 -d '{"body":"string","is_internal":null}'
1fetch("http://localhost:8000/conversations/example/messages", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "body": "string",
6 "is_internal": null
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/conversations/example/messages",
5 json={"body":"string","is_internal":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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.

Handled by api_create_conversation_draft
Parameters
conversation_id string · path
required
Responses
200Successful Response
POST /conversations/example/drafts
1curl -X POST "http://localhost:8000/conversations/example/drafts"
1fetch("http://localhost:8000/conversations/example/drafts", { method: "POST" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.post("http://localhost:8000/conversations/example/drafts")
4print(response.json())
200 Example Response
No Body
POST /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.

Handled by api_send_conversation_draft
Parameters
conversation_id string · path
required
draft_id string · path
required
Responses
200Successful Response
POST /conversations/example/drafts/example/send
1curl -X POST "http://localhost:8000/conversations/example/drafts/example/send"
1fetch("http://localhost:8000/conversations/example/drafts/example/send", { method: "POST" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.post("http://localhost:8000/conversations/example/drafts/example/send")
4print(response.json())
200 Example Response
No Body
PUT /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.

Handled by api_update_support_settings
Body · UpdateSupportSettingsapplication/json
mailboxes array
auto_reply_enabled
auto_reply_body string
sla object
resolution object
canned_replies array
statuses array
types array
propertyName anything
Responses
200Successful Response
PUT /contacts/support/settings
1curl -X PUT "http://localhost:8000/contacts/support/settings" \
2 -H "Content-Type: application/json" \
3 -d '{"mailboxes":[{"mailbox_id":"string","kind":"string","id":"string","label":"string"}],"auto_reply_enabled":null,"auto_reply_body":"string","sla":{"low_hours":1,"normal_hours":1,"high_hours":1},"resolution":{"low_hours":1,"normal_hours":1,"high_hours":1},"canned_replies":[{"id":"string","title":"string","body":"string"}],"statuses":[{"key":"string","label":"string","category":null,"color":"string"}],"types":[{"key":"string","label":"string"}]}'
1fetch("http://localhost:8000/contacts/support/settings", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "mailboxes": [
6 {
7 "mailbox_id": "string",
8 "kind": "string",
9 "id": "string",
10 "label": "string"
11 }
12 ],
13 "auto_reply_enabled": null,
14 "auto_reply_body": "string",
15 "sla": {
16 "low_hours": 1,
17 "normal_hours": 1,
18 "high_hours": 1
19 },
20 "resolution": {
21 "low_hours": 1,
22 "normal_hours": 1,
23 "high_hours": 1
24 },
25 "canned_replies": [
26 {
27 "id": "string",
28 "title": "string",
29 "body": "string"
30 }
31 ],
32 "statuses": [
33 {
34 "key": "string",
35 "label": "string",
36 "category": null,
37 "color": "string"
38 }
39 ],
40 "types": [
41 {
42 "key": "string",
43 "label": "string"
44 }
45 ]
46}),
47})
48 .then((res) => res.json())
49 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/contacts/support/settings",
5 json={"mailboxes":[{"mailbox_id":"string","kind":"string","id":"string","label":"string"}],"auto_reply_enabled":null,"auto_reply_body":"string","sla":{"low_hours":1,"normal_hours":1,"high_hours":1},"resolution":{"low_hours":1,"normal_hours":1,"high_hours":1},"canned_replies":[{"id":"string","title":"string","body":"string"}],"statuses":[{"key":"string","label":"string","category":null,"color":"string"}],"types":[{"key":"string","label":"string"}]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /coupons/:code/redemptions undocumented

/coupons/:code/redemptions

POST /coupons/:code/redemptions — apply a coupon to the current workspace.

Handled by api_redeem_coupon
Parameters
code string · path
required
Responses
200Successful Response
POST /coupons/example/redemptions
1curl -X POST "http://localhost:8000/coupons/example/redemptions"
1fetch("http://localhost:8000/coupons/example/redemptions", { method: "POST" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.post("http://localhost:8000/coupons/example/redemptions")
4print(response.json())
200 Example Response
No Body
PATCH /finance/credit-notes/:entry_id

Issue/void credit note

Handled by api_patch_credit_note
Parameters
entry_id string · path
required
Body · UpdateCreditNoteStatusapplication/json
status
required
propertyName anything
Responses
200Successful Response
PATCH /finance/credit-notes/example
1curl -X PATCH "http://localhost:8000/finance/credit-notes/example" \
2 -H "Content-Type: application/json" \
3 -d '{"status":null}'
1fetch("http://localhost:8000/finance/credit-notes/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "status": null
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/finance/credit-notes/example",
5 json={"status":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /finance/credit-notes

Create a credit note

Handled by api_create_credit_note
Body · CreateCreditNoteapplication/json
date string · min length: 10
required
items array
source_entry_id string · min length: 1
required
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
Responses
200Successful Response
POST /finance/credit-notes
1curl -X POST "http://localhost:8000/finance/credit-notes" \
2 -H "Content-Type: application/json" \
3 -d '{"date":"string","items":[{"description":"string","quantity":1.5,"unit_price":1.5,"discount":1.5,"amount":1.5,"account_code":"string","product_mrn":"string","taxes":[{"name":"string","rate":1.5,"amount":1.5,"reverse_charge":null}]}],"source_entry_id":"string","contact_mrn":"string","company_mrn":"string","currency":null,"exchange_rate":1.5,"memo":"string","adjustments":[{"label":"string","type":null,"value":1.5,"amount":1.5,"account_code":"string"}],"dimensions":null,"idempotency_key":"string"}'
1fetch("http://localhost:8000/finance/credit-notes", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "date": "string",
6 "items": [
7 {
8 "description": "string",
9 "quantity": 1.5,
10 "unit_price": 1.5,
11 "discount": 1.5,
12 "amount": 1.5,
13 "account_code": "string",
14 "product_mrn": "string",
15 "taxes": [
16 {
17 "name": "string",
18 "rate": 1.5,
19 "amount": 1.5,
20 "reverse_charge": null
21 }
22 ]
23 }
24 ],
25 "source_entry_id": "string",
26 "contact_mrn": "string",
27 "company_mrn": "string",
28 "currency": null,
29 "exchange_rate": 1.5,
30 "memo": "string",
31 "adjustments": [
32 {
33 "label": "string",
34 "type": null,
35 "value": 1.5,
36 "amount": 1.5,
37 "account_code": "string"
38 }
39 ],
40 "dimensions": null,
41 "idempotency_key": "string"
42}),
43})
44 .then((res) => res.json())
45 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/finance/credit-notes",
5 json={"date":"string","items":[{"description":"string","quantity":1.5,"unit_price":1.5,"discount":1.5,"amount":1.5,"account_code":"string","product_mrn":"string","taxes":[{"name":"string","rate":1.5,"amount":1.5,"reverse_charge":null}]}],"source_entry_id":"string","contact_mrn":"string","company_mrn":"string","currency":null,"exchange_rate":1.5,"memo":"string","adjustments":[{"label":"string","type":null,"value":1.5,"amount":1.5,"account_code":"string"}],"dimensions":null,"idempotency_key":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /finance/credit-notes/:entry_id/allocations

Set credit against an invoice

Handled by api_create_credit_note_allocation
Parameters
entry_id string · path
required
Body · CreateCreditNoteAllocationapplication/json
entry_id string · min length: 1
required
amount number
required
entry_amount number
propertyName anything
Responses
200Successful Response
POST /finance/credit-notes/example/allocations
1curl -X POST "http://localhost:8000/finance/credit-notes/example/allocations" \
2 -H "Content-Type: application/json" \
3 -d '{"entry_id":"string","amount":1.5,"entry_amount":1.5}'
1fetch("http://localhost:8000/finance/credit-notes/example/allocations", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "entry_id": "string",
6 "amount": 1.5,
7 "entry_amount": 1.5
8}),
9})
10 .then((res) => res.json())
11 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/finance/credit-notes/example/allocations",
5 json={"entry_id":"string","amount":1.5,"entry_amount":1.5},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /finance/credit-notes/:entry_id/pdfs

Generate credit note PDF

Handled by api_create_credit_note_pdf
Parameters
entry_id string · path
required
Body · GeneratePdfapplication/json
template string · max length: 100
propertyName anything
Responses
200Successful Response
POST /finance/credit-notes/example/pdfs
1curl -X POST "http://localhost:8000/finance/credit-notes/example/pdfs" \
2 -H "Content-Type: application/json" \
3 -d '{"template":"string"}'
1fetch("http://localhost:8000/finance/credit-notes/example/pdfs", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "template": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/finance/credit-notes/example/pdfs",
5 json={"template":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /finance/credit-notes/:entry_id/sends

Email a credit note

Handled by api_send_credit_note
Parameters
entry_id string · path
required
Body · SendCreditNoteapplication/json
to string · min length: 1 · max length: 500
required
cc string · max length: 500
subject string · max length: 300
message string · max length: 5000
propertyName anything
Responses
200Successful Response
POST /finance/credit-notes/example/sends
1curl -X POST "http://localhost:8000/finance/credit-notes/example/sends" \
2 -H "Content-Type: application/json" \
3 -d '{"to":"string","cc":"string","subject":"string","message":"string"}'
1fetch("http://localhost:8000/finance/credit-notes/example/sends", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "to": "string",
6 "cc": "string",
7 "subject": "string",
8 "message": "string"
9}),
10})
11 .then((res) => res.json())
12 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/finance/credit-notes/example/sends",
5 json={"to":"string","cc":"string","subject":"string","message":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /finance/credit-notes/:entry_id

Update a credit note

Handled by api_update_credit_note
Parameters
entry_id string · path
required
Body · UpdateCreditNoteapplication/json
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
Responses
200Successful Response
PUT /finance/credit-notes/example
1curl -X PUT "http://localhost:8000/finance/credit-notes/example" \
2 -H "Content-Type: application/json" \
3 -d '{"date":"string","items":[{"description":"string","quantity":1.5,"unit_price":1.5,"discount":1.5,"amount":1.5,"account_code":"string","product_mrn":"string","taxes":[{"name":"string","rate":1.5,"amount":1.5,"reverse_charge":null}]}],"contact_mrn":"string","company_mrn":"string","currency":null,"exchange_rate":1.5,"memo":"string","adjustments":[{"label":"string","type":null,"value":1.5,"amount":1.5,"account_code":"string"}],"dimensions":null}'
1fetch("http://localhost:8000/finance/credit-notes/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "date": "string",
6 "items": [
7 {
8 "description": "string",
9 "quantity": 1.5,
10 "unit_price": 1.5,
11 "discount": 1.5,
12 "amount": 1.5,
13 "account_code": "string",
14 "product_mrn": "string",
15 "taxes": [
16 {
17 "name": "string",
18 "rate": 1.5,
19 "amount": 1.5,
20 "reverse_charge": null
21 }
22 ]
23 }
24 ],
25 "contact_mrn": "string",
26 "company_mrn": "string",
27 "currency": null,
28 "exchange_rate": 1.5,
29 "memo": "string",
30 "adjustments": [
31 {
32 "label": "string",
33 "type": null,
34 "value": 1.5,
35 "amount": 1.5,
36 "account_code": "string"
37 }
38 ],
39 "dimensions": null
40}),
41})
42 .then((res) => res.json())
43 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/finance/credit-notes/example",
5 json={"date":"string","items":[{"description":"string","quantity":1.5,"unit_price":1.5,"discount":1.5,"amount":1.5,"account_code":"string","product_mrn":"string","taxes":[{"name":"string","rate":1.5,"amount":1.5,"reverse_charge":null}]}],"contact_mrn":"string","company_mrn":"string","currency":null,"exchange_rate":1.5,"memo":"string","adjustments":[{"label":"string","type":null,"value":1.5,"amount":1.5,"account_code":"string"}],"dimensions":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
GET /crm/leads undocumented

/crm/leads

Contacts with no open deal, their own or their company's, ranked by score.

Handled by api_list_leads
Responses
200Successful Response
GET /crm/leads
1curl "http://localhost:8000/crm/leads"
1fetch("http://localhost:8000/crm/leads")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/crm/leads")
4print(response.json())
200 Example Response
No Body
GET /crm/reports/pipeline undocumented

/crm/reports/pipeline

Handled by api_report_pipeline
Responses
200Successful Response
GET /crm/reports/pipeline
1curl "http://localhost:8000/crm/reports/pipeline"
1fetch("http://localhost:8000/crm/reports/pipeline")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/crm/reports/pipeline")
4print(response.json())
200 Example Response
No Body
GET /crm/reports/performance undocumented

/crm/reports/performance

Handled by api_report_performance
Responses
200Successful Response
GET /crm/reports/performance
1curl "http://localhost:8000/crm/reports/performance"
1fetch("http://localhost:8000/crm/reports/performance")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/crm/reports/performance")
4print(response.json())
200 Example Response
No Body
GET /crm/reports/forecast undocumented

/crm/reports/forecast

Handled by api_report_forecast
Responses
200Successful Response
GET /crm/reports/forecast
1curl "http://localhost:8000/crm/reports/forecast"
1fetch("http://localhost:8000/crm/reports/forecast")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/crm/reports/forecast")
4print(response.json())
200 Example Response
No Body
GET /crm/reports/activity undocumented

/crm/reports/activity

Activity report: target progress per rep.

Handled by api_report_activity
Responses
200Successful Response
GET /crm/reports/activity
1curl "http://localhost:8000/crm/reports/activity"
1fetch("http://localhost:8000/crm/reports/activity")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/crm/reports/activity")
4print(response.json())
200 Example Response
No Body
GET /crm/reports/funnel undocumented

/crm/reports/funnel

Stage entry counts + conversion, from the indexed timeline.

Handled by api_report_funnel
Responses
200Successful Response
GET /crm/reports/funnel
1curl "http://localhost:8000/crm/reports/funnel"
1fetch("http://localhost:8000/crm/reports/funnel")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/crm/reports/funnel")
4print(response.json())
200 Example Response
No Body
GET /crm/reports/trends undocumented

/crm/reports/trends

Monthly won/lost counts and won value (grouped by currency), last 12 months.

Handled by api_report_trends
Responses
200Successful Response
GET /crm/reports/trends
1curl "http://localhost:8000/crm/reports/trends"
1fetch("http://localhost:8000/crm/reports/trends")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/crm/reports/trends")
4print(response.json())
200 Example Response
No Body
GET /crm/reports/losses undocumented

/crm/reports/losses

Loss reasons breakdown (count + value by currency).

Handled by api_report_losses
Responses
200Successful Response
GET /crm/reports/losses
1curl "http://localhost:8000/crm/reports/losses"
1fetch("http://localhost:8000/crm/reports/losses")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/crm/reports/losses")
4print(response.json())
200 Example Response
No Body
DELETE /deals/:deal_id undocumented

/deals/:deal_id

Handled by api_delete_deal
Parameters
deal_id string · path
required
Responses
200Successful Response
DELETE /deals/example
1curl -X DELETE "http://localhost:8000/deals/example"
1fetch("http://localhost:8000/deals/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/deals/example")
4print(response.json())
200 Example Response
No Body
DELETE /deals/:deal_id/line-items/:item_id undocumented

/deals/:deal_id/line-items/:item_id

Handled by api_delete_line_item
Parameters
deal_id string · path
required
item_id string · path
required
Responses
200Successful Response
DELETE /deals/example/line-items/example
1curl -X DELETE "http://localhost:8000/deals/example/line-items/example"
1fetch("http://localhost:8000/deals/example/line-items/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/deals/example/line-items/example")
4print(response.json())
200 Example Response
No Body
DELETE /deals/:deal_id/links/:link_id undocumented

/deals/:deal_id/links/:link_id

Handled by api_revoke_deal_link
Parameters
deal_id string · path
required
link_id string · path
required
Responses
200Successful Response
DELETE /deals/example/links/example
1curl -X DELETE "http://localhost:8000/deals/example/links/example"
1fetch("http://localhost:8000/deals/example/links/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/deals/example/links/example")
4print(response.json())
200 Example Response
No Body
DELETE /deals/:deal_id/attachments/:file_id undocumented

/deals/:deal_id/attachments/:file_id

Handled by api_remove_deal_attachment
Parameters
deal_id string · path
required
file_id string · path
required
Responses
200Successful Response
DELETE /deals/example/attachments/example
1curl -X DELETE "http://localhost:8000/deals/example/attachments/example"
1fetch("http://localhost:8000/deals/example/attachments/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/deals/example/attachments/example")
4print(response.json())
200 Example Response
No Body
DELETE /deals/:deal_id/checklist-items/:item_id undocumented

/deals/:deal_id/checklist-items/:item_id

Handled by api_delete_checklist_item
Parameters
deal_id string · path
required
item_id string · path
required
Responses
200Successful Response
DELETE /deals/example/checklist-items/example
1curl -X DELETE "http://localhost:8000/deals/example/checklist-items/example"
1fetch("http://localhost:8000/deals/example/checklist-items/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/deals/example/checklist-items/example")
4print(response.json())
200 Example Response
No Body
GET /deals undocumented

/deals

Global deal list. pipeline_id is an optional filter, no longer mandatory.

Handled by api_list_deals
Responses
200Successful Response
GET /deals
1curl "http://localhost:8000/deals"
1fetch("http://localhost:8000/deals")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/deals")
4print(response.json())
200 Example Response
No Body
GET /deals/:deal_id undocumented

/deals/:deal_id

Handled by api_get_deal
Parameters
deal_id string · path
required
Responses
200Successful Response
GET /deals/example
1curl "http://localhost:8000/deals/example"
1fetch("http://localhost:8000/deals/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/deals/example")
4print(response.json())
200 Example Response
No Body
GET /deals/:deal_id/line-items undocumented

/deals/:deal_id/line-items

Handled by api_list_line_items
Parameters
deal_id string · path
required
Responses
200Successful Response
GET /deals/example/line-items
1curl "http://localhost:8000/deals/example/line-items"
1fetch("http://localhost:8000/deals/example/line-items")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/deals/example/line-items")
4print(response.json())
200 Example Response
No Body
GET /deals/:deal_id/links undocumented

/deals/:deal_id/links

Handled by api_list_deal_links
Parameters
deal_id string · path
required
Responses
200Successful Response
GET /deals/example/links
1curl "http://localhost:8000/deals/example/links"
1fetch("http://localhost:8000/deals/example/links")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/deals/example/links")
4print(response.json())
200 Example Response
No Body
GET /deals/:deal_id/activities undocumented

/deals/:deal_id/activities

Handled by api_list_activities
Parameters
deal_id string · path
required
Responses
200Successful Response
GET /deals/example/activities
1curl "http://localhost:8000/deals/example/activities"
1fetch("http://localhost:8000/deals/example/activities")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/deals/example/activities")
4print(response.json())
200 Example Response
No Body
GET /deals/:deal_id/checklist-items undocumented

/deals/:deal_id/checklist-items

Handled by api_list_checklist_items
Parameters
deal_id string · path
required
Responses
200Successful Response
GET /deals/example/checklist-items
1curl "http://localhost:8000/deals/example/checklist-items"
1fetch("http://localhost:8000/deals/example/checklist-items")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/deals/example/checklist-items")
4print(response.json())
200 Example Response
No Body
PATCH /deals/:deal_id/stage

Move a deal to another stage

Handled by api_move_deal_stage
Parameters
deal_id string · path
required
Body · MoveDealStageapplication/json
stage_id string · min length: 1
required
pipeline_id string
loss_reason string · max length: 1000
propertyName anything
Responses
200Successful Response
PATCH /deals/example/stage
1curl -X PATCH "http://localhost:8000/deals/example/stage" \
2 -H "Content-Type: application/json" \
3 -d '{"stage_id":"string","pipeline_id":"string","loss_reason":"string"}'
1fetch("http://localhost:8000/deals/example/stage", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "stage_id": "string",
6 "pipeline_id": "string",
7 "loss_reason": "string"
8}),
9})
10 .then((res) => res.json())
11 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/deals/example/stage",
5 json={"stage_id":"string","pipeline_id":"string","loss_reason":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /deals

Create a deal

Handled by api_create_deal
Body · CreateDealapplication/json
pipeline_id string
required
title string · min length: 1 · max length: 300
required
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
Responses
200Successful Response
POST /deals
1curl -X POST "http://localhost:8000/deals" \
2 -H "Content-Type: application/json" \
3 -d '{"pipeline_id":"string","title":"string","value":1.5,"currency":"string","stage_id":"string","contact_mrn":"string","company_mrn":"string","owner_mrn":"string","expected_close_date":"string","source":null,"line_items":[{"name":"string","product_mrn":"string","quantity":1.5,"unit_price":1.5,"currency":"string","period":null}],"tags":["string"]}'
1fetch("http://localhost:8000/deals", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "pipeline_id": "string",
6 "title": "string",
7 "value": 1.5,
8 "currency": "string",
9 "stage_id": "string",
10 "contact_mrn": "string",
11 "company_mrn": "string",
12 "owner_mrn": "string",
13 "expected_close_date": "string",
14 "source": null,
15 "line_items": [
16 {
17 "name": "string",
18 "product_mrn": "string",
19 "quantity": 1.5,
20 "unit_price": 1.5,
21 "currency": "string",
22 "period": null
23 }
24 ],
25 "tags": [
26 "string"
27 ]
28}),
29})
30 .then((res) => res.json())
31 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/deals",
5 json={"pipeline_id":"string","title":"string","value":1.5,"currency":"string","stage_id":"string","contact_mrn":"string","company_mrn":"string","owner_mrn":"string","expected_close_date":"string","source":null,"line_items":[{"name":"string","product_mrn":"string","quantity":1.5,"unit_price":1.5,"currency":"string","period":null}],"tags":["string"]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /deals/:deal_id/line-items

Add a line item to a deal

Handled by api_create_line_item
Parameters
deal_id string · path
required
Body · LineItemInapplication/json
name string · min length: 1 · max length: 200
required
product_mrn string
quantity number
unit_price number
currency string
period
propertyName anything
Responses
200Successful Response
POST /deals/example/line-items
1curl -X POST "http://localhost:8000/deals/example/line-items" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","product_mrn":"string","quantity":1.5,"unit_price":1.5,"currency":"string","period":null}'
1fetch("http://localhost:8000/deals/example/line-items", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "product_mrn": "string",
7 "quantity": 1.5,
8 "unit_price": 1.5,
9 "currency": "string",
10 "period": null
11}),
12})
13 .then((res) => res.json())
14 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/deals/example/line-items",
5 json={"name":"string","product_mrn":"string","quantity":1.5,"unit_price":1.5,"currency":"string","period":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /deals/:deal_id/links

Mint a deal room link for a customer

Handled by api_create_deal_link
Parameters
deal_id string · path
required
Body · CreateDealLinkapplication/json
label string · max length: 200
propertyName anything
Responses
200Successful Response
POST /deals/example/links
1curl -X POST "http://localhost:8000/deals/example/links" \
2 -H "Content-Type: application/json" \
3 -d '{"label":"string"}'
1fetch("http://localhost:8000/deals/example/links", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "label": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/deals/example/links",
5 json={"label":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /deals/:deal_id/attachments

Attach a shared file to the deal room

Handled by api_add_deal_attachment
Parameters
deal_id string · path
required
Body · CreateDealAttachmentapplication/json
mrn string · min length: 15 · max length: 200
required
name string · min length: 1 · max length: 300
required
url string · min length: 1 · max length: 500
required
share_id string · max length: 100
propertyName anything
Responses
200Successful Response
POST /deals/example/attachments
1curl -X POST "http://localhost:8000/deals/example/attachments" \
2 -H "Content-Type: application/json" \
3 -d '{"mrn":"string","name":"string","url":"string","share_id":"string"}'
1fetch("http://localhost:8000/deals/example/attachments", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "mrn": "string",
6 "name": "string",
7 "url": "string",
8 "share_id": "string"
9}),
10})
11 .then((res) => res.json())
12 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/deals/example/attachments",
5 json={"mrn":"string","name":"string","url":"string","share_id":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /deals/:deal_id/activities

Add a note to a deal

Handled by api_create_note
Parameters
deal_id string · path
required
Body · CreateNoteapplication/json
content string · min length: 1 · max length: 20000
required
application_id string · max length: 100
propertyName anything
Responses
200Successful Response
POST /deals/example/activities
1curl -X POST "http://localhost:8000/deals/example/activities" \
2 -H "Content-Type: application/json" \
3 -d '{"content":"string","application_id":"string"}'
1fetch("http://localhost:8000/deals/example/activities", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "content": "string",
6 "application_id": "string"
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/deals/example/activities",
5 json={"content":"string","application_id":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /deals/:deal_id/checklist-items

Add a checklist item to a deal

Handled by api_create_checklist_item
Parameters
deal_id string · path
required
Body · CreateChecklistItemapplication/json
label string · min length: 1 · max length: 200
required
stage_id string
assignee_mrn string
due_date string
propertyName anything
Responses
200Successful Response
POST /deals/example/checklist-items
1curl -X POST "http://localhost:8000/deals/example/checklist-items" \
2 -H "Content-Type: application/json" \
3 -d '{"label":"string","stage_id":"string","assignee_mrn":"string","due_date":"string"}'
1fetch("http://localhost:8000/deals/example/checklist-items", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "label": "string",
6 "stage_id": "string",
7 "assignee_mrn": "string",
8 "due_date": "string"
9}),
10})
11 .then((res) => res.json())
12 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/deals/example/checklist-items",
5 json={"label":"string","stage_id":"string","assignee_mrn":"string","due_date":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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).

Handled by api_create_quote_request
Parameters
deal_id string · path
required
Body · CreateQuoteRequestapplication/json
memo string · max length: 2000
propertyName anything
Responses
200Successful Response
POST /deals/example/quote-requests
1curl -X POST "http://localhost:8000/deals/example/quote-requests" \
2 -H "Content-Type: application/json" \
3 -d '{"memo":"string"}'
1fetch("http://localhost:8000/deals/example/quote-requests", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "memo": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/deals/example/quote-requests",
5 json={"memo":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /deals/:deal_id

Update a deal

Handled by api_update_deal
Parameters
deal_id string · path
required
Body · UpdateDealapplication/json
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
Responses
200Successful Response
PUT /deals/example
1curl -X PUT "http://localhost:8000/deals/example" \
2 -H "Content-Type: application/json" \
3 -d '{"title":"string","value":1.5,"currency":"string","contact_mrn":"string","company_mrn":"string","owner_mrn":"string","expected_close_date":"string","source":null,"tags":["string"],"loss_reason":"string","proposal":"string"}'
1fetch("http://localhost:8000/deals/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "title": "string",
6 "value": 1.5,
7 "currency": "string",
8 "contact_mrn": "string",
9 "company_mrn": "string",
10 "owner_mrn": "string",
11 "expected_close_date": "string",
12 "source": null,
13 "tags": [
14 "string"
15 ],
16 "loss_reason": "string",
17 "proposal": "string"
18}),
19})
20 .then((res) => res.json())
21 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/deals/example",
5 json={"title":"string","value":1.5,"currency":"string","contact_mrn":"string","company_mrn":"string","owner_mrn":"string","expected_close_date":"string","source":null,"tags":["string"],"loss_reason":"string","proposal":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /deals/:deal_id/line-items/:item_id

Update a deal line item

Handled by api_update_line_item
Parameters
deal_id string · path
required
item_id string · path
required
Body · UpdateLineItemapplication/json
name string · min length: 1 · max length: 200
product_mrn string
quantity number
unit_price number
currency string
period
position integer
propertyName anything
Responses
200Successful Response
PUT /deals/example/line-items/example
1curl -X PUT "http://localhost:8000/deals/example/line-items/example" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","product_mrn":"string","quantity":1.5,"unit_price":1.5,"currency":"string","period":null,"position":1}'
1fetch("http://localhost:8000/deals/example/line-items/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "product_mrn": "string",
7 "quantity": 1.5,
8 "unit_price": 1.5,
9 "currency": "string",
10 "period": null,
11 "position": 1
12}),
13})
14 .then((res) => res.json())
15 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/deals/example/line-items/example",
5 json={"name":"string","product_mrn":"string","quantity":1.5,"unit_price":1.5,"currency":"string","period":null,"position":1},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /deals/:deal_id/checklist-items/:item_id

Update a deal checklist item

Handled by api_update_checklist_item
Parameters
deal_id string · path
required
item_id string · path
required
Body · UpdateChecklistItemapplication/json
done
label string · min length: 1 · max length: 200
assignee_mrn string
due_date string
position integer
propertyName anything
Responses
200Successful Response
PUT /deals/example/checklist-items/example
1curl -X PUT "http://localhost:8000/deals/example/checklist-items/example" \
2 -H "Content-Type: application/json" \
3 -d '{"done":null,"label":"string","assignee_mrn":"string","due_date":"string","position":1}'
1fetch("http://localhost:8000/deals/example/checklist-items/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "done": null,
6 "label": "string",
7 "assignee_mrn": "string",
8 "due_date": "string",
9 "position": 1
10}),
11})
12 .then((res) => res.json())
13 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/deals/example/checklist-items/example",
5 json={"done":null,"label":"string","assignee_mrn":"string","due_date":"string","position":1},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
DELETE /decks/trash undocumented

/decks/trash

DELETE /decks/trash. Destroy every trashed deck the caller manages.

Handled by api_empty_trash
Responses
200Successful Response
DELETE /decks/trash
1curl -X DELETE "http://localhost:8000/decks/trash"
1fetch("http://localhost:8000/decks/trash", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/decks/trash")
4print(response.json())
200 Example Response
No Body
DELETE /decks/trash/:id undocumented

/decks/trash/:id

DELETE /decks/trash/:id. Destroy a trashed deck. Gate loaded ctx.authz.deck.

Handled by api_purge_deck
Parameters
id string · path
required
Responses
200Successful Response
DELETE /decks/trash/example
1curl -X DELETE "http://localhost:8000/decks/trash/example"
1fetch("http://localhost:8000/decks/trash/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/decks/trash/example")
4print(response.json())
200 Example Response
No Body
DELETE /decks/:id undocumented

/decks/:id

DELETE /decks/:id. Soft-delete. Grants stay so restore still works.

Handled by api_delete_deck
Parameters
id string · path
required
Responses
200Successful Response
DELETE /decks/example
1curl -X DELETE "http://localhost:8000/decks/example"
1fetch("http://localhost:8000/decks/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/decks/example")
4print(response.json())
200 Example Response
No Body
GET /decks undocumented

/decks

GET /decks. Decks the caller can access.

Handled by api_list_decks
Responses
200Successful Response
GET /decks
1curl "http://localhost:8000/decks"
1fetch("http://localhost:8000/decks")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/decks")
4print(response.json())
200 Example Response
No Body
GET /decks/trash undocumented

/decks/trash

GET /decks/trash. Decks in the trash that the caller can restore.

Handled by api_list_trash
Responses
200Successful Response
GET /decks/trash
1curl "http://localhost:8000/decks/trash"
1fetch("http://localhost:8000/decks/trash")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/decks/trash")
4print(response.json())
200 Example Response
No Body
GET /decks/:id undocumented

/decks/:id

GET /decks/:id. Metadata + deck_json. Gate loaded ctx.authz.deck.

Handled by api_get_deck
Parameters
id string · path
required
Responses
200Successful Response
GET /decks/example
1curl "http://localhost:8000/decks/example"
1fetch("http://localhost:8000/decks/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/decks/example")
4print(response.json())
200 Example Response
No Body
GET /decks/:id/exports/:format undocumented

/decks/:id/exports/:format

GET /decks/:id/exports/:format: the deck as an .odp download.

Handled by api_export_deck
Parameters
id string · path
required
format string · path
required
Responses
200Successful Response
GET /decks/example/exports/example
1curl "http://localhost:8000/decks/example/exports/example"
1fetch("http://localhost:8000/decks/example/exports/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/decks/example/exports/example")
4print(response.json())
200 Example Response
No Body
GET /decks/:id/assets undocumented

/decks/:id/assets

GET /decks/:id/assets. Images uploaded to this deck. Gate loaded ctx.authz.deck.

Handled by api_list_assets
Parameters
id string · path
required
Responses
200Successful Response
GET /decks/example/assets
1curl "http://localhost:8000/decks/example/assets"
1fetch("http://localhost:8000/decks/example/assets")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/decks/example/assets")
4print(response.json())
200 Example Response
No Body
DELETE /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.

Handled by api_delete_deliverable
Parameters
deliverable_id string · path
required
Responses
200Successful Response
DELETE /deliverables/example
1curl -X DELETE "http://localhost:8000/deliverables/example"
1fetch("http://localhost:8000/deliverables/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/deliverables/example")
4print(response.json())
200 Example Response
No Body
GET /deliverables undocumented

/deliverables

GET /deliverables?board_id=...&q=... — list a board's deliverables.

Handled by api_list_deliverables
Responses
200Successful Response
GET /deliverables
1curl "http://localhost:8000/deliverables"
1fetch("http://localhost:8000/deliverables")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/deliverables")
4print(response.json())
200 Example Response
No Body
POST /deliverables

Create a deliverable

Handled by api_create_deliverable
Body · CreateDeliverableapplication/json
board_id string
required
name string · min length: 1 · max length: 200
required
due_date string · min length: 1
required
description string · max length: 5000
status
schedule_id string
owner_mrn string
propertyName anything
Responses
200Successful Response
POST /deliverables
1curl -X POST "http://localhost:8000/deliverables" \
2 -H "Content-Type: application/json" \
3 -d '{"board_id":"string","name":"string","due_date":"string","description":"string","status":null,"schedule_id":"string","owner_mrn":"string"}'
1fetch("http://localhost:8000/deliverables", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "board_id": "string",
6 "name": "string",
7 "due_date": "string",
8 "description": "string",
9 "status": null,
10 "schedule_id": "string",
11 "owner_mrn": "string"
12}),
13})
14 .then((res) => res.json())
15 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/deliverables",
5 json={"board_id":"string","name":"string","due_date":"string","description":"string","status":null,"schedule_id":"string","owner_mrn":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /deliverables/:deliverable_id

Update a deliverable

Handled by api_update_deliverable
Parameters
deliverable_id string · path
required
Body · UpdateDeliverableapplication/json
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
Responses
200Successful Response
PUT /deliverables/example
1curl -X PUT "http://localhost:8000/deliverables/example" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","description":"string","due_date":"string","status":null,"schedule_id":"string","owner_mrn":"string"}'
1fetch("http://localhost:8000/deliverables/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "description": "string",
7 "due_date": "string",
8 "status": null,
9 "schedule_id": "string",
10 "owner_mrn": "string"
11}),
12})
13 .then((res) => res.json())
14 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/deliverables/example",
5 json={"name":"string","description":"string","due_date":"string","status":null,"schedule_id":"string","owner_mrn":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
GET /demo-requests/availability undocumented

/demo-requests/availability

GET /demo-requests/availability — open demo slots for the next weekdays.

Handled by availability
Responses
200Successful Response
GET /demo-requests/availability
1curl "http://localhost:8000/demo-requests/availability"
1fetch("http://localhost:8000/demo-requests/availability")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/demo-requests/availability")
4print(response.json())
200 Example Response
No Body
DELETE /departments/:department_id undocumented

/departments/:department_id

Handled by api_delete_department
Parameters
department_id string · path
required
Responses
200Successful Response
DELETE /departments/example
1curl -X DELETE "http://localhost:8000/departments/example"
1fetch("http://localhost:8000/departments/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/departments/example")
4print(response.json())
200 Example Response
No Body
DELETE /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.

Handled by api_remove_department_member
Parameters
department_id string · path
required
worker_id string · path
required
Responses
200Successful Response
DELETE /departments/example/members/example
1curl -X DELETE "http://localhost:8000/departments/example/members/example"
1fetch("http://localhost:8000/departments/example/members/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/departments/example/members/example")
4print(response.json())
200 Example Response
No Body
GET /departments undocumented

/departments

Handled by api_list_departments
Responses
200Successful Response
GET /departments
1curl "http://localhost:8000/departments"
1fetch("http://localhost:8000/departments")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/departments")
4print(response.json())
200 Example Response
No Body
GET /departments/:department_id undocumented

/departments/:department_id

Handled by api_get_department
Parameters
department_id string · path
required
Responses
200Successful Response
GET /departments/example
1curl "http://localhost:8000/departments/example"
1fetch("http://localhost:8000/departments/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/departments/example")
4print(response.json())
200 Example Response
No Body
PATCH /departments/:department_id

Update a department

Handled by api_update_department
Parameters
department_id string · path
required
Body · UpdateDepartmentapplication/json
name string · min length: 1 · max length: 100
description string · max length: 1000
parent_id string
head_mrn string
propertyName anything
Responses
200Successful Response
PATCH /departments/example
1curl -X PATCH "http://localhost:8000/departments/example" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","description":"string","parent_id":"string","head_mrn":"string"}'
1fetch("http://localhost:8000/departments/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "description": "string",
7 "parent_id": "string",
8 "head_mrn": "string"
9}),
10})
11 .then((res) => res.json())
12 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/departments/example",
5 json={"name":"string","description":"string","parent_id":"string","head_mrn":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /departments

Create a department

Handled by api_create_department
Body · CreateDepartmentapplication/json
name string · min length: 1 · max length: 100
required
description string · max length: 1000
parent_id string
head_mrn string
propertyName anything
Responses
200Successful Response
POST /departments
1curl -X POST "http://localhost:8000/departments" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","description":"string","parent_id":"string","head_mrn":"string"}'
1fetch("http://localhost:8000/departments", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "description": "string",
7 "parent_id": "string",
8 "head_mrn": "string"
9}),
10})
11 .then((res) => res.json())
12 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/departments",
5 json={"name":"string","description":"string","parent_id":"string","head_mrn":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /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.

Handled by api_add_department_member
Parameters
department_id string · path
required
worker_id string · path
required
Responses
200Successful Response
PUT /departments/example/members/example
1curl -X PUT "http://localhost:8000/departments/example/members/example"
1fetch("http://localhost:8000/departments/example/members/example", { method: "PUT" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.put("http://localhost:8000/departments/example/members/example")
4print(response.json())
200 Example Response
No Body
PATCH /finance/dimensions/:dimension_key

Update a dimension

Handled by api_patch_dimension
Parameters
dimension_key string · path
required
Body · DimensionDefapplication/json
name string · min length: 1 · max length: 100
required
key string · min length: 1 · max length: 50
required
values array
required
propertyName anything
Responses
200Successful Response
PATCH /finance/dimensions/example
1curl -X PATCH "http://localhost:8000/finance/dimensions/example" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","key":"string","values":["string"]}'
1fetch("http://localhost:8000/finance/dimensions/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "key": "string",
7 "values": [
8 "string"
9 ]
10}),
11})
12 .then((res) => res.json())
13 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/finance/dimensions/example",
5 json={"name":"string","key":"string","values":["string"]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /finance/dimensions

Define a dimension

Handled by api_create_dimension
Body · DimensionDefapplication/json
name string · min length: 1 · max length: 100
required
key string · min length: 1 · max length: 50
required
values array
required
propertyName anything
Responses
200Successful Response
POST /finance/dimensions
1curl -X POST "http://localhost:8000/finance/dimensions" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","key":"string","values":["string"]}'
1fetch("http://localhost:8000/finance/dimensions", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "key": "string",
7 "values": [
8 "string"
9 ]
10}),
11})
12 .then((res) => res.json())
13 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/finance/dimensions",
5 json={"name":"string","key":"string","values":["string"]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /sign/envelopes/:envelope_id

Update document metadata

PATCH /sign/envelopes/:envelope_id — update metadata OR transition state (sent/voided).

Handled by api_update_envelope
Parameters
envelope_id string · path
required
Body · UpdateEnvelopeapplication/json
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
Responses
200Successful Response
PATCH /sign/envelopes/example
1curl -X PATCH "http://localhost:8000/sign/envelopes/example" \
2 -H "Content-Type: application/json" \
3 -d '{"title":"string","subject":"string","message":"string","signing_order_mode":null,"jurisdiction":"string","expires_at":"string","status":null,"reason":"string"}'
1fetch("http://localhost:8000/sign/envelopes/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "title": "string",
6 "subject": "string",
7 "message": "string",
8 "signing_order_mode": null,
9 "jurisdiction": "string",
10 "expires_at": "string",
11 "status": null,
12 "reason": "string"
13}),
14})
15 .then((res) => res.json())
16 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/sign/envelopes/example",
5 json={"title":"string","subject":"string","message":"string","signing_order_mode":null,"jurisdiction":"string","expires_at":"string","status":null,"reason":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /sign/envelopes

Create a draft document

POST /sign/envelopes — create a draft (optionally cloning ?template_id).

Handled by api_create_envelope
Body · CreateEnvelopeapplication/json
title string · min length: 1 · max length: 300
required
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
Responses
200Successful Response
POST /sign/envelopes
1curl -X POST "http://localhost:8000/sign/envelopes" \
2 -H "Content-Type: application/json" \
3 -d '{"title":"string","subject":"string","message":"string","template_id":"string","signing_order_mode":null,"jurisdiction":"string","is_template":null,"source_mrn":"string"}'
1fetch("http://localhost:8000/sign/envelopes", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "title": "string",
6 "subject": "string",
7 "message": "string",
8 "template_id": "string",
9 "signing_order_mode": null,
10 "jurisdiction": "string",
11 "is_template": null,
12 "source_mrn": "string"
13}),
14})
15 .then((res) => res.json())
16 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/sign/envelopes",
5 json={"title":"string","subject":"string","message":"string","template_id":"string","signing_order_mode":null,"jurisdiction":"string","is_template":null,"source_mrn":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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.

Handled by api_add_document
Parameters
envelope_id string · path
required
Body · AttachDocumentapplication/json
storage_key string · min length: 1 · max length: 500
required
title string · max length: 300
page_count integer
propertyName anything
Responses
200Successful Response
POST /sign/envelopes/example/documents
1curl -X POST "http://localhost:8000/sign/envelopes/example/documents" \
2 -H "Content-Type: application/json" \
3 -d '{"storage_key":"string","title":"string","page_count":1}'
1fetch("http://localhost:8000/sign/envelopes/example/documents", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "storage_key": "string",
6 "title": "string",
7 "page_count": 1
8}),
9})
10 .then((res) => res.json())
11 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/sign/envelopes/example/documents",
5 json={"storage_key":"string","title":"string","page_count":1},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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.

Handled by api_create_export
Parameters
envelope_id string · path
required
Body · ExportEnvelopeapplication/json
target
required
propertyName anything
Responses
200Successful Response
POST /sign/envelopes/example/exports
1curl -X POST "http://localhost:8000/sign/envelopes/example/exports" \
2 -H "Content-Type: application/json" \
3 -d '{"target":null}'
1fetch("http://localhost:8000/sign/envelopes/example/exports", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "target": null
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/sign/envelopes/example/exports",
5 json={"target":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /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.

Handled by api_attach_source
Parameters
envelope_id string · path
required
Body · AttachSourceapplication/json
storage_key string · min length: 1 · max length: 500
required
page_count integer
propertyName anything
Responses
200Successful Response
PUT /sign/envelopes/example/source
1curl -X PUT "http://localhost:8000/sign/envelopes/example/source" \
2 -H "Content-Type: application/json" \
3 -d '{"storage_key":"string","page_count":1}'
1fetch("http://localhost:8000/sign/envelopes/example/source", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "storage_key": "string",
6 "page_count": 1
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/sign/envelopes/example/source",
5 json={"storage_key":"string","page_count":1},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /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.

Handled by api_update_settings
Body · UpdateSignSettingsapplication/json
contract_template_id string · max length: 64
propertyName anything
Responses
200Successful Response
PUT /sign/settings
1curl -X PUT "http://localhost:8000/sign/settings" \
2 -H "Content-Type: application/json" \
3 -d '{"contract_template_id":"string"}'
1fetch("http://localhost:8000/sign/settings", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "contract_template_id": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/sign/settings",
5 json={"contract_template_id":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
DELETE /elevations undocumented

/elevations

DELETE /elevations — leave admin mode without waiting for the timer.

Handled by api_end_elevation
Responses
200Successful Response
DELETE /elevations
1curl -X DELETE "http://localhost:8000/elevations"
1fetch("http://localhost:8000/elevations", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/elevations")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_current_elevation
Responses
200Successful Response
GET /elevations/current
1curl "http://localhost:8000/elevations/current"
1fetch("http://localhost:8000/elevations/current")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/elevations/current")
4print(response.json())
200 Example Response
No Body
POST /workers/:worker_id/employment

Add an employment record

Handled by api_create_employment
Parameters
worker_id string · path
required
Body · CreateEmploymentapplication/json
job_title string · min length: 1 · max length: 200
required
start_date string · min length: 1 · max length: 10
required
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
Responses
200Successful Response
POST /workers/example/employment
1curl -X POST "http://localhost:8000/workers/example/employment" \
2 -H "Content-Type: application/json" \
3 -d '{"job_title":"string","start_date":"string","member_mrn":"string","employment_type":null,"end_date":"string","reason":"string","reminder_enabled":null,"reminder_days_before":1}'
1fetch("http://localhost:8000/workers/example/employment", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "job_title": "string",
6 "start_date": "string",
7 "member_mrn": "string",
8 "employment_type": null,
9 "end_date": "string",
10 "reason": "string",
11 "reminder_enabled": null,
12 "reminder_days_before": 1
13}),
14})
15 .then((res) => res.json())
16 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/workers/example/employment",
5 json={"job_title":"string","start_date":"string","member_mrn":"string","employment_type":null,"end_date":"string","reason":"string","reminder_enabled":null,"reminder_days_before":1},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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.

Handled by api_terminate_worker
Parameters
worker_id string · path
required
Body · TerminateWorkerapplication/json
reason string · min length: 1 · max length: 500
required
effective_date string · min length: 1 · max length: 10
required
propertyName anything
Responses
200Successful Response
POST /workers/example/employment/termination
1curl -X POST "http://localhost:8000/workers/example/employment/termination" \
2 -H "Content-Type: application/json" \
3 -d '{"reason":"string","effective_date":"string"}'
1fetch("http://localhost:8000/workers/example/employment/termination", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "reason": "string",
6 "effective_date": "string"
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/workers/example/employment/termination",
5 json={"reason":"string","effective_date":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /workers/:worker_id/employment/:record_id

Update an employment record

Handled by api_update_employment
Parameters
worker_id string · path
required
record_id string · path
required
Body · UpdateEmploymentapplication/json
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
Responses
200Successful Response
PUT /workers/example/employment/example
1curl -X PUT "http://localhost:8000/workers/example/employment/example" \
2 -H "Content-Type: application/json" \
3 -d '{"job_title":"string","employment_type":null,"start_date":"string","end_date":"string","reason":"string","reminder_enabled":null,"reminder_days_before":1}'
1fetch("http://localhost:8000/workers/example/employment/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "job_title": "string",
6 "employment_type": null,
7 "start_date": "string",
8 "end_date": "string",
9 "reason": "string",
10 "reminder_enabled": null,
11 "reminder_days_before": 1
12}),
13})
14 .then((res) => res.json())
15 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/workers/example/employment/example",
5 json={"job_title":"string","employment_type":null,"start_date":"string","end_date":"string","reason":"string","reminder_enabled":null,"reminder_days_before":1},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
GET /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.

Handled by api_get_exchange
Parameters
exchange_id string · path
required
Responses
200Successful Response
GET /exchanges/example
1curl "http://localhost:8000/exchanges/example"
1fetch("http://localhost:8000/exchanges/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/exchanges/example")
4print(response.json())
200 Example Response
No Body
PATCH /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.

Handled by api_update_field
Parameters
envelope_id string · path
required
field_id string · path
required
Body · UpdateFieldapplication/json
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
Responses
200Successful Response
PATCH /sign/envelopes/example/fields/example
1curl -X PATCH "http://localhost:8000/sign/envelopes/example/fields/example" \
2 -H "Content-Type: application/json" \
3 -d '{"role":"string","recipient_id":"string","kind":null,"page_number":1,"nx":1.5,"ny":1.5,"nw":1.5,"nh":1.5,"label":"string","required":null,"default_value":"string","options":{"choices":["string"],"show_if":{"field_id":"string","equals":"string"}}}'
1fetch("http://localhost:8000/sign/envelopes/example/fields/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "role": "string",
6 "recipient_id": "string",
7 "kind": null,
8 "page_number": 1,
9 "nx": 1.5,
10 "ny": 1.5,
11 "nw": 1.5,
12 "nh": 1.5,
13 "label": "string",
14 "required": null,
15 "default_value": "string",
16 "options": {
17 "choices": [
18 "string"
19 ],
20 "show_if": {
21 "field_id": "string",
22 "equals": "string"
23 }
24 }
25}),
26})
27 .then((res) => res.json())
28 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/sign/envelopes/example/fields/example",
5 json={"role":"string","recipient_id":"string","kind":null,"page_number":1,"nx":1.5,"ny":1.5,"nw":1.5,"nh":1.5,"label":"string","required":null,"default_value":"string","options":{"choices":["string"],"show_if":{"field_id":"string","equals":"string"}}},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /sign/envelopes/:envelope_id/fields

Add field placements

POST /sign/envelopes/:envelope_id/fields — add one or more field placements (bulk).

Handled by api_create_fields
Parameters
envelope_id string · path
required
Body · CreateFieldsapplication/json
fields array
required
propertyName anything
Responses
200Successful Response
POST /sign/envelopes/example/fields
1curl -X POST "http://localhost:8000/sign/envelopes/example/fields" \
2 -H "Content-Type: application/json" \
3 -d '{"fields":[{"role":"string","recipient_id":"string","kind":null,"page_number":1,"nx":1.5,"ny":1.5,"nw":1.5,"nh":1.5,"label":"string","required":null,"default_value":"string","options":{"choices":["string"],"show_if":{"field_id":"string","equals":"string"}}}]}'
1fetch("http://localhost:8000/sign/envelopes/example/fields", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "fields": [
6 {
7 "role": "string",
8 "recipient_id": "string",
9 "kind": null,
10 "page_number": 1,
11 "nx": 1.5,
12 "ny": 1.5,
13 "nw": 1.5,
14 "nh": 1.5,
15 "label": "string",
16 "required": null,
17 "default_value": "string",
18 "options": {
19 "choices": [
20 "string"
21 ],
22 "show_if": {
23 "field_id": "string",
24 "equals": "string"
25 }
26 }
27 }
28 ]
29}),
30})
31 .then((res) => res.json())
32 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/sign/envelopes/example/fields",
5 json={"fields":[{"role":"string","recipient_id":"string","kind":null,"page_number":1,"nx":1.5,"ny":1.5,"nw":1.5,"nh":1.5,"label":"string","required":null,"default_value":"string","options":{"choices":["string"],"show_if":{"field_id":"string","equals":"string"}}}]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
GET /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, ...).

Handled by api_file_statistics
Responses
200Successful Response
GET /file-statistics
1curl "http://localhost:8000/file-statistics"
1fetch("http://localhost:8000/file-statistics")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/file-statistics")
4print(response.json())
200 Example Response
No Body
DELETE /files/:file_id undocumented

/files/:file_id

Handled by api_delete_file
Parameters
file_id string · path
required
Responses
200Successful Response
DELETE /files/example
1curl -X DELETE "http://localhost:8000/files/example"
1fetch("http://localhost:8000/files/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/files/example")
4print(response.json())
200 Example Response
No Body
DELETE /files/:file_id/stars undocumented

/files/:file_id/stars

DELETE /files/:file_id/stars — remove the current member's star.

Handled by api_unstar_file
Parameters
file_id string · path
required
Responses
200Successful Response
DELETE /files/example/stars
1curl -X DELETE "http://localhost:8000/files/example/stars"
1fetch("http://localhost:8000/files/example/stars", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/files/example/stars")
4print(response.json())
200 Example Response
No Body
DELETE /files/:file_id/permissions undocumented

/files/:file_id/permissions

Handled by api_revoke_file_permission
Parameters
file_id string · path
required
Responses
200Successful Response
DELETE /files/example/permissions
1curl -X DELETE "http://localhost:8000/files/example/permissions"
1fetch("http://localhost:8000/files/example/permissions", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/files/example/permissions")
4print(response.json())
200 Example Response
No Body
GET /files undocumented

/files

Handled by api_list_files
Responses
200Successful Response
GET /files
1curl "http://localhost:8000/files"
1fetch("http://localhost:8000/files")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/files")
4print(response.json())
200 Example Response
No Body
GET /files/:file_id undocumented

/files/:file_id

Handled by api_get_file
Parameters
file_id string · path
required
Responses
200Successful Response
GET /files/example
1curl "http://localhost:8000/files/example"
1fetch("http://localhost:8000/files/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/files/example")
4print(response.json())
200 Example Response
No Body
GET /files/:file_id/download undocumented

/files/:file_id/download

Handled by api_download_file
Parameters
file_id string · path
required
Responses
200Successful Response
GET /files/example/download
1curl "http://localhost:8000/files/example/download"
1fetch("http://localhost:8000/files/example/download")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/files/example/download")
4print(response.json())
200 Example Response
No Body
GET /files/:file_id/preview undocumented

/files/:file_id/preview

GET /files/:file_id/preview — presigned URL for inline preview.

Handled by api_preview_file
Parameters
file_id string · path
required
Responses
200Successful Response
GET /files/example/preview
1curl "http://localhost:8000/files/example/preview"
1fetch("http://localhost:8000/files/example/preview")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/files/example/preview")
4print(response.json())
200 Example Response
No Body
GET /files/:file_id/versions undocumented

/files/:file_id/versions

GET /files/:file_id/versions — version history, newest first.

Handled by api_list_file_versions
Parameters
file_id string · path
required
Responses
200Successful Response
GET /files/example/versions
1curl "http://localhost:8000/files/example/versions"
1fetch("http://localhost:8000/files/example/versions")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/files/example/versions")
4print(response.json())
200 Example Response
No Body
GET /files/:file_id/permissions undocumented

/files/:file_id/permissions

Handled by api_list_file_permissions
Parameters
file_id string · path
required
Responses
200Successful Response
GET /files/example/permissions
1curl "http://localhost:8000/files/example/permissions"
1fetch("http://localhost:8000/files/example/permissions")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/files/example/permissions")
4print(response.json())
200 Example Response
No Body
PATCH /files/:file_id

Update a file

Handled by api_update_file
Parameters
file_id string · path
required
Body · UpdateFileapplication/json
name string · min length: 1 · max length: 255
folder_id string
is_starred
restore_version_id string
propertyName anything
Responses
200Successful Response
PATCH /files/example
1curl -X PATCH "http://localhost:8000/files/example" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","folder_id":"string","is_starred":null,"restore_version_id":"string"}'
1fetch("http://localhost:8000/files/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "folder_id": "string",
7 "is_starred": null,
8 "restore_version_id": "string"
9}),
10})
11 .then((res) => res.json())
12 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/files/example",
5 json={"name":"string","folder_id":"string","is_starred":null,"restore_version_id":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /files/:file_id/stars undocumented

/files/:file_id/stars

POST /files/:file_id/stars — star a file for the current member.

Handled by api_star_file
Parameters
file_id string · path
required
Responses
200Successful Response
POST /files/example/stars
1curl -X POST "http://localhost:8000/files/example/stars"
1fetch("http://localhost:8000/files/example/stars", { method: "POST" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.post("http://localhost:8000/files/example/stars")
4print(response.json())
200 Example Response
No Body
POST /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.

Handled by api_copy_file
Parameters
file_id string · path
required
Body · CopyFileapplication/json
folder_id string
propertyName anything
Responses
200Successful Response
POST /files/example/copies
1curl -X POST "http://localhost:8000/files/example/copies" \
2 -H "Content-Type: application/json" \
3 -d '{"folder_id":"string"}'
1fetch("http://localhost:8000/files/example/copies", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "folder_id": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/files/example/copies",
5 json={"folder_id":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /files/bulk

Bulk file operation

Handled by api_bulk_operation
Body · BulkOperationapplication/json
action
required
ids array
required
folder_id string
propertyName anything
Responses
200Successful Response
POST /files/bulk
1curl -X POST "http://localhost:8000/files/bulk" \
2 -H "Content-Type: application/json" \
3 -d '{"action":null,"ids":["string"],"folder_id":"string"}'
1fetch("http://localhost:8000/files/bulk", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "action": null,
6 "ids": [
7 "string"
8 ],
9 "folder_id": "string"
10}),
11})
12 .then((res) => res.json())
13 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/files/bulk",
5 json={"action":null,"ids":["string"],"folder_id":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
DELETE /finance/quotes/:entry_id undocumented

/finance/quotes/:entry_id

Handled by api_delete_quote
Parameters
entry_id string · path
required
Responses
200Successful Response
DELETE /finance/quotes/example
1curl -X DELETE "http://localhost:8000/finance/quotes/example"
1fetch("http://localhost:8000/finance/quotes/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/finance/quotes/example")
4print(response.json())
200 Example Response
No Body
DELETE /finance/purchase-orders/:entry_id undocumented

/finance/purchase-orders/:entry_id

Handled by api_delete_purchase_order
Parameters
entry_id string · path
required
Responses
200Successful Response
DELETE /finance/purchase-orders/example
1curl -X DELETE "http://localhost:8000/finance/purchase-orders/example"
1fetch("http://localhost:8000/finance/purchase-orders/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/finance/purchase-orders/example")
4print(response.json())
200 Example Response
No Body
DELETE /finance/orders/:entry_id undocumented

/finance/orders/:entry_id

Handled by api_delete_order
Parameters
entry_id string · path
required
Responses
200Successful Response
DELETE /finance/orders/example
1curl -X DELETE "http://localhost:8000/finance/orders/example"
1fetch("http://localhost:8000/finance/orders/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/finance/orders/example")
4print(response.json())
200 Example Response
No Body
DELETE /finance/invoices/:entry_id undocumented

/finance/invoices/:entry_id

Handled by api_delete_invoice
Parameters
entry_id string · path
required
Responses
200Successful Response
DELETE /finance/invoices/example
1curl -X DELETE "http://localhost:8000/finance/invoices/example"
1fetch("http://localhost:8000/finance/invoices/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/finance/invoices/example")
4print(response.json())
200 Example Response
No Body
DELETE /finance/invoices/:entry_id/attachments/:attachment_id undocumented

/finance/invoices/:entry_id/attachments/:attachment_id

Handled by api_delete_invoice_attachment
Parameters
entry_id string · path
required
attachment_id string · path
required
Responses
200Successful Response
DELETE /finance/invoices/example/attachments/example
1curl -X DELETE "http://localhost:8000/finance/invoices/example/attachments/example"
1fetch("http://localhost:8000/finance/invoices/example/attachments/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/finance/invoices/example/attachments/example")
4print(response.json())
200 Example Response
No Body
DELETE /finance/bills/:entry_id undocumented

/finance/bills/:entry_id

Handled by api_delete_bill
Parameters
entry_id string · path
required
Responses
200Successful Response
DELETE /finance/bills/example
1curl -X DELETE "http://localhost:8000/finance/bills/example"
1fetch("http://localhost:8000/finance/bills/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/finance/bills/example")
4print(response.json())
200 Example Response
No Body
DELETE /finance/credit-notes/:entry_id undocumented

/finance/credit-notes/:entry_id

Handled by api_delete_credit_note
Parameters
entry_id string · path
required
Responses
200Successful Response
DELETE /finance/credit-notes/example
1curl -X DELETE "http://localhost:8000/finance/credit-notes/example"
1fetch("http://localhost:8000/finance/credit-notes/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/finance/credit-notes/example")
4print(response.json())
200 Example Response
No Body
DELETE /finance/credit-notes/:entry_id/allocations/:target_entry_id undocumented

/finance/credit-notes/:entry_id/allocations/:target_entry_id

Handled by api_delete_credit_note_allocation
Parameters
entry_id string · path
required
target_entry_id string · path
required
Responses
200Successful Response
DELETE /finance/credit-notes/example/allocations/example
1curl -X DELETE "http://localhost:8000/finance/credit-notes/example/allocations/example"
1fetch("http://localhost:8000/finance/credit-notes/example/allocations/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/finance/credit-notes/example/allocations/example")
4print(response.json())
200 Example Response
No Body
DELETE /finance/credit-notes/:entry_id/attachments/:attachment_id undocumented

/finance/credit-notes/:entry_id/attachments/:attachment_id

Handled by api_delete_credit_note_attachment
Parameters
entry_id string · path
required
attachment_id string · path
required
Responses
200Successful Response
DELETE /finance/credit-notes/example/attachments/example
1curl -X DELETE "http://localhost:8000/finance/credit-notes/example/attachments/example"
1fetch("http://localhost:8000/finance/credit-notes/example/attachments/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/finance/credit-notes/example/attachments/example")
4print(response.json())
200 Example Response
No Body
DELETE /finance/purchase-credit-notes/:entry_id undocumented

/finance/purchase-credit-notes/:entry_id

Handled by api_delete_purchase_credit_note
Parameters
entry_id string · path
required
Responses
200Successful Response
DELETE /finance/purchase-credit-notes/example
1curl -X DELETE "http://localhost:8000/finance/purchase-credit-notes/example"
1fetch("http://localhost:8000/finance/purchase-credit-notes/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/finance/purchase-credit-notes/example")
4print(response.json())
200 Example Response
No Body
DELETE /finance/purchase-credit-notes/:entry_id/allocations/:target_entry_id undocumented

/finance/purchase-credit-notes/:entry_id/allocations/:target_entry_id

Handled by api_delete_purchase_credit_note_allocation
Parameters
entry_id string · path
required
target_entry_id string · path
required
Responses
200Successful Response
DELETE /finance/purchase-credit-notes/example/allocations/example
1curl -X DELETE "http://localhost:8000/finance/purchase-credit-notes/example/allocations/example"
1fetch("http://localhost:8000/finance/purchase-credit-notes/example/allocations/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/finance/purchase-credit-notes/example/allocations/example")
4print(response.json())
200 Example Response
No Body
DELETE /finance/journal-entries/:entry_id undocumented

/finance/journal-entries/:entry_id

Handled by api_delete_journal_entry
Parameters
entry_id string · path
required
Responses
200Successful Response
DELETE /finance/journal-entries/example
1curl -X DELETE "http://localhost:8000/finance/journal-entries/example"
1fetch("http://localhost:8000/finance/journal-entries/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/finance/journal-entries/example")
4print(response.json())
200 Example Response
No Body
DELETE /finance/accounts/:account_id undocumented

/finance/accounts/:account_id

Handled by api_delete_account
Parameters
account_id string · path
required
Responses
200Successful Response
DELETE /finance/accounts/example
1curl -X DELETE "http://localhost:8000/finance/accounts/example"
1fetch("http://localhost:8000/finance/accounts/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/finance/accounts/example")
4print(response.json())
200 Example Response
No Body
DELETE /finance/bank-imports/:import_id undocumented

/finance/bank-imports/:import_id

Handled by api_delete_bank_import
Parameters
import_id string · path
required
Responses
200Successful Response
DELETE /finance/bank-imports/example
1curl -X DELETE "http://localhost:8000/finance/bank-imports/example"
1fetch("http://localhost:8000/finance/bank-imports/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/finance/bank-imports/example")
4print(response.json())
200 Example Response
No Body
DELETE /finance/requests/:request_id undocumented

/finance/requests/:request_id

DELETE /finance/requests/:id — the owner withdraws a submitted request.

Handled by api_cancel_request
Parameters
request_id string · path
required
Responses
200Successful Response
DELETE /finance/requests/example
1curl -X DELETE "http://localhost:8000/finance/requests/example"
1fetch("http://localhost:8000/finance/requests/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/finance/requests/example")
4print(response.json())
200 Example Response
No Body
DELETE /finance/links/:link_id undocumented

/finance/links/:link_id

Handled by api_revoke_link
Parameters
link_id string · path
required
Responses
200Successful Response
DELETE /finance/links/example
1curl -X DELETE "http://localhost:8000/finance/links/example"
1fetch("http://localhost:8000/finance/links/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/finance/links/example")
4print(response.json())
200 Example Response
No Body
DELETE /finance/payment-credentials/:provider undocumented

/finance/payment-credentials/:provider

Handled by api_delete_payment_credentials
Parameters
provider string · path
required
Responses
200Successful Response
DELETE /finance/payment-credentials/example
1curl -X DELETE "http://localhost:8000/finance/payment-credentials/example"
1fetch("http://localhost:8000/finance/payment-credentials/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/finance/payment-credentials/example")
4print(response.json())
200 Example Response
No Body
DELETE /finance/bank-connections/:id undocumented

/finance/bank-connections/:id

Handled by api_delete_bank_connection
Parameters
id string · path
required
Responses
200Successful Response
DELETE /finance/bank-connections/example
1curl -X DELETE "http://localhost:8000/finance/bank-connections/example"
1fetch("http://localhost:8000/finance/bank-connections/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/finance/bank-connections/example")
4print(response.json())
200 Example Response
No Body
DELETE /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.

Handled by api_delete_logo
Responses
200Successful Response
DELETE /finance/settings/logo
1curl -X DELETE "http://localhost:8000/finance/settings/logo"
1fetch("http://localhost:8000/finance/settings/logo", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/finance/settings/logo")
4print(response.json())
200 Example Response
No Body
DELETE /finance/fiscal-periods/:period_id undocumented

/finance/fiscal-periods/:period_id

Handled by api_delete_fiscal_period
Parameters
period_id string · path
required
Responses
200Successful Response
DELETE /finance/fiscal-periods/example
1curl -X DELETE "http://localhost:8000/finance/fiscal-periods/example"
1fetch("http://localhost:8000/finance/fiscal-periods/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/finance/fiscal-periods/example")
4print(response.json())
200 Example Response
No Body
DELETE /finance/dimensions/:dimension_key undocumented

/finance/dimensions/:dimension_key

Handled by api_delete_dimension
Parameters
dimension_key string · path
required
Responses
200Successful Response
DELETE /finance/dimensions/example
1curl -X DELETE "http://localhost:8000/finance/dimensions/example"
1fetch("http://localhost:8000/finance/dimensions/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/finance/dimensions/example")
4print(response.json())
200 Example Response
No Body
DELETE /finance/tax-rates/:tax_id undocumented

/finance/tax-rates/:tax_id

Handled by handler
Parameters
tax_id string · path
required
Responses
200Successful Response
DELETE /finance/tax-rates/example
1curl -X DELETE "http://localhost:8000/finance/tax-rates/example"
1fetch("http://localhost:8000/finance/tax-rates/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/finance/tax-rates/example")
4print(response.json())
200 Example Response
No Body
DELETE /finance/payment-terms/:term_id undocumented

/finance/payment-terms/:term_id

Handled by handler
Parameters
term_id string · path
required
Responses
200Successful Response
DELETE /finance/payment-terms/example
1curl -X DELETE "http://localhost:8000/finance/payment-terms/example"
1fetch("http://localhost:8000/finance/payment-terms/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/finance/payment-terms/example")
4print(response.json())
200 Example Response
No Body
DELETE /finance/bank-rules/:rule_id undocumented

/finance/bank-rules/:rule_id

Handled by handler
Parameters
rule_id string · path
required
Responses
200Successful Response
DELETE /finance/bank-rules/example
1curl -X DELETE "http://localhost:8000/finance/bank-rules/example"
1fetch("http://localhost:8000/finance/bank-rules/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/finance/bank-rules/example")
4print(response.json())
200 Example Response
No Body
DELETE /finance/budgets/:budget_id undocumented

/finance/budgets/:budget_id

Handled by handler
Parameters
budget_id string · path
required
Responses
200Successful Response
DELETE /finance/budgets/example
1curl -X DELETE "http://localhost:8000/finance/budgets/example"
1fetch("http://localhost:8000/finance/budgets/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/finance/budgets/example")
4print(response.json())
200 Example Response
No Body
DELETE /finance/recurring-entries/:recurring_id undocumented

/finance/recurring-entries/:recurring_id

Handled by handler
Parameters
recurring_id string · path
required
Responses
200Successful Response
DELETE /finance/recurring-entries/example
1curl -X DELETE "http://localhost:8000/finance/recurring-entries/example"
1fetch("http://localhost:8000/finance/recurring-entries/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/finance/recurring-entries/example")
4print(response.json())
200 Example Response
No Body
GET /finance/quotes undocumented

/finance/quotes

Handled by api_list_quotes
Responses
200Successful Response
GET /finance/quotes
1curl "http://localhost:8000/finance/quotes"
1fetch("http://localhost:8000/finance/quotes")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/quotes")
4print(response.json())
200 Example Response
No Body
GET /finance/quotes/:entry_id undocumented

/finance/quotes/:entry_id

Handled by api_get_quote
Parameters
entry_id string · path
required
Responses
200Successful Response
GET /finance/quotes/example
1curl "http://localhost:8000/finance/quotes/example"
1fetch("http://localhost:8000/finance/quotes/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/quotes/example")
4print(response.json())
200 Example Response
No Body
GET /finance/purchase-orders undocumented

/finance/purchase-orders

Handled by api_list_purchase_orders
Responses
200Successful Response
GET /finance/purchase-orders
1curl "http://localhost:8000/finance/purchase-orders"
1fetch("http://localhost:8000/finance/purchase-orders")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/purchase-orders")
4print(response.json())
200 Example Response
No Body
GET /finance/purchase-orders/:entry_id undocumented

/finance/purchase-orders/:entry_id

Handled by api_get_purchase_order
Parameters
entry_id string · path
required
Responses
200Successful Response
GET /finance/purchase-orders/example
1curl "http://localhost:8000/finance/purchase-orders/example"
1fetch("http://localhost:8000/finance/purchase-orders/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/purchase-orders/example")
4print(response.json())
200 Example Response
No Body
GET /finance/purchase-orders/:entry_id/receipts undocumented

/finance/purchase-orders/:entry_id/receipts

Handled by api_list_receipts
Parameters
entry_id string · path
required
Responses
200Successful Response
GET /finance/purchase-orders/example/receipts
1curl "http://localhost:8000/finance/purchase-orders/example/receipts"
1fetch("http://localhost:8000/finance/purchase-orders/example/receipts")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/purchase-orders/example/receipts")
4print(response.json())
200 Example Response
No Body
GET /finance/orders undocumented

/finance/orders

Handled by api_list_orders
Responses
200Successful Response
GET /finance/orders
1curl "http://localhost:8000/finance/orders"
1fetch("http://localhost:8000/finance/orders")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/orders")
4print(response.json())
200 Example Response
No Body
GET /finance/orders/:entry_id undocumented

/finance/orders/:entry_id

Handled by api_get_order
Parameters
entry_id string · path
required
Responses
200Successful Response
GET /finance/orders/example
1curl "http://localhost:8000/finance/orders/example"
1fetch("http://localhost:8000/finance/orders/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/orders/example")
4print(response.json())
200 Example Response
No Body
GET /finance/orders/:entry_id/fulfillments undocumented

/finance/orders/:entry_id/fulfillments

Handled by api_list_fulfillments
Parameters
entry_id string · path
required
Responses
200Successful Response
GET /finance/orders/example/fulfillments
1curl "http://localhost:8000/finance/orders/example/fulfillments"
1fetch("http://localhost:8000/finance/orders/example/fulfillments")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/orders/example/fulfillments")
4print(response.json())
200 Example Response
No Body
GET /finance/invoices undocumented

/finance/invoices

Handled by api_list_invoices
Responses
200Successful Response
GET /finance/invoices
1curl "http://localhost:8000/finance/invoices"
1fetch("http://localhost:8000/finance/invoices")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/invoices")
4print(response.json())
200 Example Response
No Body
GET /finance/invoices/:entry_id undocumented

/finance/invoices/:entry_id

Handled by api_get_invoice
Parameters
entry_id string · path
required
Responses
200Successful Response
GET /finance/invoices/example
1curl "http://localhost:8000/finance/invoices/example"
1fetch("http://localhost:8000/finance/invoices/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/invoices/example")
4print(response.json())
200 Example Response
No Body
GET /finance/invoices/:entry_id/payments undocumented

/finance/invoices/:entry_id/payments

Handled by api_list_invoice_payments
Parameters
entry_id string · path
required
Responses
200Successful Response
GET /finance/invoices/example/payments
1curl "http://localhost:8000/finance/invoices/example/payments"
1fetch("http://localhost:8000/finance/invoices/example/payments")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/invoices/example/payments")
4print(response.json())
200 Example Response
No Body
GET /finance/invoices/:entry_id/ledger-lines undocumented

/finance/invoices/:entry_id/ledger-lines

Handled by api_list_invoice_ledger_lines
Parameters
entry_id string · path
required
Responses
200Successful Response
GET /finance/invoices/example/ledger-lines
1curl "http://localhost:8000/finance/invoices/example/ledger-lines"
1fetch("http://localhost:8000/finance/invoices/example/ledger-lines")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/invoices/example/ledger-lines")
4print(response.json())
200 Example Response
No Body
GET /finance/invoices/:entry_id/pdfs undocumented

/finance/invoices/:entry_id/pdfs

Handled by api_list_invoice_pdfs
Parameters
entry_id string · path
required
Responses
200Successful Response
GET /finance/invoices/example/pdfs
1curl "http://localhost:8000/finance/invoices/example/pdfs"
1fetch("http://localhost:8000/finance/invoices/example/pdfs")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/invoices/example/pdfs")
4print(response.json())
200 Example Response
No Body
GET /finance/bills undocumented

/finance/bills

Handled by api_list_bills
Responses
200Successful Response
GET /finance/bills
1curl "http://localhost:8000/finance/bills"
1fetch("http://localhost:8000/finance/bills")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/bills")
4print(response.json())
200 Example Response
No Body
GET /finance/bills/:entry_id undocumented

/finance/bills/:entry_id

Handled by api_get_bill
Parameters
entry_id string · path
required
Responses
200Successful Response
GET /finance/bills/example
1curl "http://localhost:8000/finance/bills/example"
1fetch("http://localhost:8000/finance/bills/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/bills/example")
4print(response.json())
200 Example Response
No Body
GET /finance/bills/:entry_id/payments undocumented

/finance/bills/:entry_id/payments

Handled by api_list_bill_payments
Parameters
entry_id string · path
required
Responses
200Successful Response
GET /finance/bills/example/payments
1curl "http://localhost:8000/finance/bills/example/payments"
1fetch("http://localhost:8000/finance/bills/example/payments")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/bills/example/payments")
4print(response.json())
200 Example Response
No Body
GET /finance/bills/:entry_id/ledger-lines undocumented

/finance/bills/:entry_id/ledger-lines

Handled by api_list_bill_ledger_lines
Parameters
entry_id string · path
required
Responses
200Successful Response
GET /finance/bills/example/ledger-lines
1curl "http://localhost:8000/finance/bills/example/ledger-lines"
1fetch("http://localhost:8000/finance/bills/example/ledger-lines")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/bills/example/ledger-lines")
4print(response.json())
200 Example Response
No Body
GET /finance/credit-notes undocumented

/finance/credit-notes

Handled by api_list_credit_notes
Responses
200Successful Response
GET /finance/credit-notes
1curl "http://localhost:8000/finance/credit-notes"
1fetch("http://localhost:8000/finance/credit-notes")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/credit-notes")
4print(response.json())
200 Example Response
No Body
GET /finance/credit-notes/:entry_id undocumented

/finance/credit-notes/:entry_id

Handled by api_get_credit_note
Parameters
entry_id string · path
required
Responses
200Successful Response
GET /finance/credit-notes/example
1curl "http://localhost:8000/finance/credit-notes/example"
1fetch("http://localhost:8000/finance/credit-notes/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/credit-notes/example")
4print(response.json())
200 Example Response
No Body
GET /finance/credit-notes/:entry_id/ledger-lines undocumented

/finance/credit-notes/:entry_id/ledger-lines

Handled by api_list_credit_note_ledger_lines
Parameters
entry_id string · path
required
Responses
200Successful Response
GET /finance/credit-notes/example/ledger-lines
1curl "http://localhost:8000/finance/credit-notes/example/ledger-lines"
1fetch("http://localhost:8000/finance/credit-notes/example/ledger-lines")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/credit-notes/example/ledger-lines")
4print(response.json())
200 Example Response
No Body
GET /finance/credit-notes/:entry_id/pdfs undocumented

/finance/credit-notes/:entry_id/pdfs

Handled by api_list_credit_note_pdfs
Parameters
entry_id string · path
required
Responses
200Successful Response
GET /finance/credit-notes/example/pdfs
1curl "http://localhost:8000/finance/credit-notes/example/pdfs"
1fetch("http://localhost:8000/finance/credit-notes/example/pdfs")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/credit-notes/example/pdfs")
4print(response.json())
200 Example Response
No Body
GET /finance/purchase-credit-notes undocumented

/finance/purchase-credit-notes

Handled by api_list_purchase_credit_notes
Responses
200Successful Response
GET /finance/purchase-credit-notes
1curl "http://localhost:8000/finance/purchase-credit-notes"
1fetch("http://localhost:8000/finance/purchase-credit-notes")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/purchase-credit-notes")
4print(response.json())
200 Example Response
No Body
GET /finance/purchase-credit-notes/:entry_id undocumented

/finance/purchase-credit-notes/:entry_id

Handled by api_get_purchase_credit_note
Parameters
entry_id string · path
required
Responses
200Successful Response
GET /finance/purchase-credit-notes/example
1curl "http://localhost:8000/finance/purchase-credit-notes/example"
1fetch("http://localhost:8000/finance/purchase-credit-notes/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/purchase-credit-notes/example")
4print(response.json())
200 Example Response
No Body
GET /finance/purchase-credit-notes/:entry_id/ledger-lines undocumented

/finance/purchase-credit-notes/:entry_id/ledger-lines

Handled by api_list_purchase_credit_note_ledger_lines
Parameters
entry_id string · path
required
Responses
200Successful Response
GET /finance/purchase-credit-notes/example/ledger-lines
1curl "http://localhost:8000/finance/purchase-credit-notes/example/ledger-lines"
1fetch("http://localhost:8000/finance/purchase-credit-notes/example/ledger-lines")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/purchase-credit-notes/example/ledger-lines")
4print(response.json())
200 Example Response
No Body
GET /finance/journal-entries undocumented

/finance/journal-entries

Handled by api_list_journal_entries
Responses
200Successful Response
GET /finance/journal-entries
1curl "http://localhost:8000/finance/journal-entries"
1fetch("http://localhost:8000/finance/journal-entries")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/journal-entries")
4print(response.json())
200 Example Response
No Body
GET /finance/journal-entries/:entry_id undocumented

/finance/journal-entries/:entry_id

Handled by api_get_journal_entry
Parameters
entry_id string · path
required
Responses
200Successful Response
GET /finance/journal-entries/example
1curl "http://localhost:8000/finance/journal-entries/example"
1fetch("http://localhost:8000/finance/journal-entries/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/journal-entries/example")
4print(response.json())
200 Example Response
No Body
GET /finance/journal-entries/:entry_id/ledger-lines undocumented

/finance/journal-entries/:entry_id/ledger-lines

Handled by api_list_journal_ledger_lines
Parameters
entry_id string · path
required
Responses
200Successful Response
GET /finance/journal-entries/example/ledger-lines
1curl "http://localhost:8000/finance/journal-entries/example/ledger-lines"
1fetch("http://localhost:8000/finance/journal-entries/example/ledger-lines")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/journal-entries/example/ledger-lines")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_list_accounts
Responses
200Successful Response
GET /finance/accounts
1curl "http://localhost:8000/finance/accounts"
1fetch("http://localhost:8000/finance/accounts")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/accounts")
4print(response.json())
200 Example Response
No Body
GET /finance/accounts/:account_id undocumented

/finance/accounts/:account_id

Handled by api_get_account
Parameters
account_id string · path
required
Responses
200Successful Response
GET /finance/accounts/example
1curl "http://localhost:8000/finance/accounts/example"
1fetch("http://localhost:8000/finance/accounts/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/accounts/example")
4print(response.json())
200 Example Response
No Body
GET /finance/accounts/:account_id/ledger-lines undocumented

/finance/accounts/:account_id/ledger-lines

Handled by api_list_account_ledger_lines
Parameters
account_id string · path
required
Responses
200Successful Response
GET /finance/accounts/example/ledger-lines
1curl "http://localhost:8000/finance/accounts/example/ledger-lines"
1fetch("http://localhost:8000/finance/accounts/example/ledger-lines")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/accounts/example/ledger-lines")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_chart_advice
Responses
200Successful Response
GET /finance/chart-advice
1curl "http://localhost:8000/finance/chart-advice"
1fetch("http://localhost:8000/finance/chart-advice")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/chart-advice")
4print(response.json())
200 Example Response
No Body
GET /finance/ledger undocumented

/finance/ledger

Handled by api_list_ledger_lines
Responses
200Successful Response
GET /finance/ledger
1curl "http://localhost:8000/finance/ledger"
1fetch("http://localhost:8000/finance/ledger")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/ledger")
4print(response.json())
200 Example Response
No Body
GET /finance/ledger/:line_id undocumented

/finance/ledger/:line_id

Handled by api_get_ledger_line
Parameters
line_id string · path
required
Responses
200Successful Response
GET /finance/ledger/example
1curl "http://localhost:8000/finance/ledger/example"
1fetch("http://localhost:8000/finance/ledger/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/ledger/example")
4print(response.json())
200 Example Response
No Body
GET /finance/payments undocumented

/finance/payments

Handled by api_list_payments
Responses
200Successful Response
GET /finance/payments
1curl "http://localhost:8000/finance/payments"
1fetch("http://localhost:8000/finance/payments")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/payments")
4print(response.json())
200 Example Response
No Body
GET /finance/payments/:payment_id undocumented

/finance/payments/:payment_id

Handled by api_get_payment
Parameters
payment_id string · path
required
Responses
200Successful Response
GET /finance/payments/example
1curl "http://localhost:8000/finance/payments/example"
1fetch("http://localhost:8000/finance/payments/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/payments/example")
4print(response.json())
200 Example Response
No Body
GET /finance/payments/:payment_id/reversals undocumented

/finance/payments/:payment_id/reversals

Handled by api_list_payment_reversals
Parameters
payment_id string · path
required
Responses
200Successful Response
GET /finance/payments/example/reversals
1curl "http://localhost:8000/finance/payments/example/reversals"
1fetch("http://localhost:8000/finance/payments/example/reversals")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/payments/example/reversals")
4print(response.json())
200 Example Response
No Body
GET /finance/bank-imports undocumented

/finance/bank-imports

Handled by api_list_bank_imports
Responses
200Successful Response
GET /finance/bank-imports
1curl "http://localhost:8000/finance/bank-imports"
1fetch("http://localhost:8000/finance/bank-imports")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/bank-imports")
4print(response.json())
200 Example Response
No Body
GET /finance/bank-imports/:import_id undocumented

/finance/bank-imports/:import_id

Handled by api_get_bank_import
Parameters
import_id string · path
required
Responses
200Successful Response
GET /finance/bank-imports/example
1curl "http://localhost:8000/finance/bank-imports/example"
1fetch("http://localhost:8000/finance/bank-imports/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/bank-imports/example")
4print(response.json())
200 Example Response
No Body
GET /finance/bank-imports/:import_id/matches undocumented

/finance/bank-imports/:import_id/matches

Handled by api_list_bank_import_matches
Parameters
import_id string · path
required
Responses
200Successful Response
GET /finance/bank-imports/example/matches
1curl "http://localhost:8000/finance/bank-imports/example/matches"
1fetch("http://localhost:8000/finance/bank-imports/example/matches")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/bank-imports/example/matches")
4print(response.json())
200 Example Response
No Body
GET /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).

Handled by api_list_requests
Responses
200Successful Response
GET /finance/requests
1curl "http://localhost:8000/finance/requests"
1fetch("http://localhost:8000/finance/requests")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/requests")
4print(response.json())
200 Example Response
No Body
GET /finance/requests/:request_id undocumented

/finance/requests/:request_id

Handled by api_get_request
Parameters
request_id string · path
required
Responses
200Successful Response
GET /finance/requests/example
1curl "http://localhost:8000/finance/requests/example"
1fetch("http://localhost:8000/finance/requests/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/requests/example")
4print(response.json())
200 Example Response
No Body
GET /finance/quotes/:entry_id/links undocumented

/finance/quotes/:entry_id/links

Handled by api_list_quote_links
Parameters
entry_id string · path
required
Responses
200Successful Response
GET /finance/quotes/example/links
1curl "http://localhost:8000/finance/quotes/example/links"
1fetch("http://localhost:8000/finance/quotes/example/links")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/quotes/example/links")
4print(response.json())
200 Example Response
No Body
GET /finance/invoices/:entry_id/links undocumented

/finance/invoices/:entry_id/links

Handled by api_list_invoice_links
Parameters
entry_id string · path
required
Responses
200Successful Response
GET /finance/invoices/example/links
1curl "http://localhost:8000/finance/invoices/example/links"
1fetch("http://localhost:8000/finance/invoices/example/links")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/invoices/example/links")
4print(response.json())
200 Example Response
No Body
GET /finance/credit-notes/:entry_id/links undocumented

/finance/credit-notes/:entry_id/links

Handled by api_list_credit_note_links
Parameters
entry_id string · path
required
Responses
200Successful Response
GET /finance/credit-notes/example/links
1curl "http://localhost:8000/finance/credit-notes/example/links"
1fetch("http://localhost:8000/finance/credit-notes/example/links")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/credit-notes/example/links")
4print(response.json())
200 Example Response
No Body
GET /finance/payment-credentials undocumented

/finance/payment-credentials

Handled by api_list_payment_credentials
Responses
200Successful Response
GET /finance/payment-credentials
1curl "http://localhost:8000/finance/payment-credentials"
1fetch("http://localhost:8000/finance/payment-credentials")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/payment-credentials")
4print(response.json())
200 Example Response
No Body
GET /finance/bank-connections undocumented

/finance/bank-connections

Handled by api_list_bank_connections
Responses
200Successful Response
GET /finance/bank-connections
1curl "http://localhost:8000/finance/bank-connections"
1fetch("http://localhost:8000/finance/bank-connections")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/bank-connections")
4print(response.json())
200 Example Response
No Body
GET /finance/reconciliations undocumented

/finance/reconciliations

Handled by api_list_reconciliations
Responses
200Successful Response
GET /finance/reconciliations
1curl "http://localhost:8000/finance/reconciliations"
1fetch("http://localhost:8000/finance/reconciliations")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/reconciliations")
4print(response.json())
200 Example Response
No Body
GET /finance/reconciliations/:recon_id undocumented

/finance/reconciliations/:recon_id

Handled by api_get_reconciliation
Parameters
recon_id string · path
required
Responses
200Successful Response
GET /finance/reconciliations/example
1curl "http://localhost:8000/finance/reconciliations/example"
1fetch("http://localhost:8000/finance/reconciliations/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/reconciliations/example")
4print(response.json())
200 Example Response
No Body
GET /finance/settings undocumented

/finance/settings

Handled by api_get_settings
Responses
200Successful Response
GET /finance/settings
1curl "http://localhost:8000/finance/settings"
1fetch("http://localhost:8000/finance/settings")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/settings")
4print(response.json())
200 Example Response
No Body
GET /finance/fiscal-periods undocumented

/finance/fiscal-periods

Handled by api_list_fiscal_periods
Responses
200Successful Response
GET /finance/fiscal-periods
1curl "http://localhost:8000/finance/fiscal-periods"
1fetch("http://localhost:8000/finance/fiscal-periods")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/fiscal-periods")
4print(response.json())
200 Example Response
No Body
GET /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=...

Handled by api_preview_revaluation
Parameters
period_id string · path
required
Responses
200Successful Response
GET /finance/fiscal-periods/example/revaluation-preview
1curl "http://localhost:8000/finance/fiscal-periods/example/revaluation-preview"
1fetch("http://localhost:8000/finance/fiscal-periods/example/revaluation-preview")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/fiscal-periods/example/revaluation-preview")
4print(response.json())
200 Example Response
No Body
GET /finance/fiscal-periods/:period_id/revaluations undocumented

/finance/fiscal-periods/:period_id/revaluations

GET /finance/fiscal-periods/:period_id/revaluations

Handled by api_list_revaluations
Parameters
period_id string · path
required
Responses
200Successful Response
GET /finance/fiscal-periods/example/revaluations
1curl "http://localhost:8000/finance/fiscal-periods/example/revaluations"
1fetch("http://localhost:8000/finance/fiscal-periods/example/revaluations")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/fiscal-periods/example/revaluations")
4print(response.json())
200 Example Response
No Body
GET /finance/dimensions undocumented

/finance/dimensions

Handled by api_list_dimensions
Responses
200Successful Response
GET /finance/dimensions
1curl "http://localhost:8000/finance/dimensions"
1fetch("http://localhost:8000/finance/dimensions")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/dimensions")
4print(response.json())
200 Example Response
No Body
GET /finance/dimensions/:dimension_key/values undocumented

/finance/dimensions/:dimension_key/values

Handled by api_list_dimension_values
Parameters
dimension_key string · path
required
Responses
200Successful Response
GET /finance/dimensions/example/values
1curl "http://localhost:8000/finance/dimensions/example/values"
1fetch("http://localhost:8000/finance/dimensions/example/values")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/dimensions/example/values")
4print(response.json())
200 Example Response
No Body
GET /finance/tax-rates undocumented

/finance/tax-rates

Handled by handler
Responses
200Successful Response
GET /finance/tax-rates
1curl "http://localhost:8000/finance/tax-rates"
1fetch("http://localhost:8000/finance/tax-rates")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/tax-rates")
4print(response.json())
200 Example Response
No Body
GET /finance/payment-terms undocumented

/finance/payment-terms

Handled by handler
Responses
200Successful Response
GET /finance/payment-terms
1curl "http://localhost:8000/finance/payment-terms"
1fetch("http://localhost:8000/finance/payment-terms")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/payment-terms")
4print(response.json())
200 Example Response
No Body
GET /finance/bank-rules undocumented

/finance/bank-rules

Handled by handler
Responses
200Successful Response
GET /finance/bank-rules
1curl "http://localhost:8000/finance/bank-rules"
1fetch("http://localhost:8000/finance/bank-rules")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/bank-rules")
4print(response.json())
200 Example Response
No Body
GET /finance/budgets undocumented

/finance/budgets

Handled by handler
Responses
200Successful Response
GET /finance/budgets
1curl "http://localhost:8000/finance/budgets"
1fetch("http://localhost:8000/finance/budgets")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/budgets")
4print(response.json())
200 Example Response
No Body
GET /finance/recurring-entries undocumented

/finance/recurring-entries

Handled by handler
Responses
200Successful Response
GET /finance/recurring-entries
1curl "http://localhost:8000/finance/recurring-entries"
1fetch("http://localhost:8000/finance/recurring-entries")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/recurring-entries")
4print(response.json())
200 Example Response
No Body
GET /finance/reports/trial-balance undocumented

/finance/reports/trial-balance

Handled by api_report_trial_balance
Responses
200Successful Response
GET /finance/reports/trial-balance
1curl "http://localhost:8000/finance/reports/trial-balance"
1fetch("http://localhost:8000/finance/reports/trial-balance")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/reports/trial-balance")
4print(response.json())
200 Example Response
No Body
GET /finance/reports/income-statement undocumented

/finance/reports/income-statement

Handled by api_report_income_statement
Responses
200Successful Response
GET /finance/reports/income-statement
1curl "http://localhost:8000/finance/reports/income-statement"
1fetch("http://localhost:8000/finance/reports/income-statement")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/reports/income-statement")
4print(response.json())
200 Example Response
No Body
GET /finance/reports/balance-sheet undocumented

/finance/reports/balance-sheet

Handled by api_report_balance_sheet
Responses
200Successful Response
GET /finance/reports/balance-sheet
1curl "http://localhost:8000/finance/reports/balance-sheet"
1fetch("http://localhost:8000/finance/reports/balance-sheet")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/reports/balance-sheet")
4print(response.json())
200 Example Response
No Body
GET /finance/reports/aged-receivables undocumented

/finance/reports/aged-receivables

Handled by api_report_aged_receivables
Responses
200Successful Response
GET /finance/reports/aged-receivables
1curl "http://localhost:8000/finance/reports/aged-receivables"
1fetch("http://localhost:8000/finance/reports/aged-receivables")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/reports/aged-receivables")
4print(response.json())
200 Example Response
No Body
GET /finance/reports/aged-payables undocumented

/finance/reports/aged-payables

Handled by api_report_aged_payables
Responses
200Successful Response
GET /finance/reports/aged-payables
1curl "http://localhost:8000/finance/reports/aged-payables"
1fetch("http://localhost:8000/finance/reports/aged-payables")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/reports/aged-payables")
4print(response.json())
200 Example Response
No Body
GET /finance/reports/cash-flow undocumented

/finance/reports/cash-flow

Handled by api_report_cash_flow
Responses
200Successful Response
GET /finance/reports/cash-flow
1curl "http://localhost:8000/finance/reports/cash-flow"
1fetch("http://localhost:8000/finance/reports/cash-flow")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/reports/cash-flow")
4print(response.json())
200 Example Response
No Body
GET /finance/reports/revenue-by-customer undocumented

/finance/reports/revenue-by-customer

Handled by api_report_revenue_by_customer
Responses
200Successful Response
GET /finance/reports/revenue-by-customer
1curl "http://localhost:8000/finance/reports/revenue-by-customer"
1fetch("http://localhost:8000/finance/reports/revenue-by-customer")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/reports/revenue-by-customer")
4print(response.json())
200 Example Response
No Body
GET /finance/reports/budget-vs-actuals undocumented

/finance/reports/budget-vs-actuals

Handled by api_report_budget_vs_actuals
Responses
200Successful Response
GET /finance/reports/budget-vs-actuals
1curl "http://localhost:8000/finance/reports/budget-vs-actuals"
1fetch("http://localhost:8000/finance/reports/budget-vs-actuals")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/reports/budget-vs-actuals")
4print(response.json())
200 Example Response
No Body
GET /finance/reports/dimensions/:dimension_key undocumented

/finance/reports/dimensions/:dimension_key

Handled by api_report_dimension_breakdown
Parameters
dimension_key string · path
required
Responses
200Successful Response
GET /finance/reports/dimensions/example
1curl "http://localhost:8000/finance/reports/dimensions/example"
1fetch("http://localhost:8000/finance/reports/dimensions/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/finance/reports/dimensions/example")
4print(response.json())
200 Example Response
No Body
POST /finance/bank-connections/:id/syncs undocumented

/finance/bank-connections/:id/syncs

Handled by api_sync_bank_connection
Parameters
id string · path
required
Responses
200Successful Response
POST /finance/bank-connections/example/syncs
1curl -X POST "http://localhost:8000/finance/bank-connections/example/syncs"
1fetch("http://localhost:8000/finance/bank-connections/example/syncs", { method: "POST" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.post("http://localhost:8000/finance/bank-connections/example/syncs")
4print(response.json())
200 Example Response
No Body
POST /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.

Handled by api_year_end_close
Parameters
period_id string · path
required
Responses
200Successful Response
POST /finance/fiscal-periods/example/year-end-close
1curl -X POST "http://localhost:8000/finance/fiscal-periods/example/year-end-close"
1fetch("http://localhost:8000/finance/fiscal-periods/example/year-end-close", { method: "POST" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.post("http://localhost:8000/finance/fiscal-periods/example/year-end-close")
4print(response.json())
200 Example Response
No Body
POST /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.

Handled by api_run_recurring
Parameters
recurring_id string · path
required
Responses
200Successful Response
POST /finance/recurring-entries/example/runs
1curl -X POST "http://localhost:8000/finance/recurring-entries/example/runs"
1fetch("http://localhost:8000/finance/recurring-entries/example/runs", { method: "POST" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.post("http://localhost:8000/finance/recurring-entries/example/runs")
4print(response.json())
200 Example Response
No Body
PUT /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.

Handled by api_put_logo
Responses
200Successful Response
PUT /finance/settings/logo
1curl -X PUT "http://localhost:8000/finance/settings/logo"
1fetch("http://localhost:8000/finance/settings/logo", { method: "PUT" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.put("http://localhost:8000/finance/settings/logo")
4print(response.json())
200 Example Response
No Body
DELETE /folders/:folder_id undocumented

/folders/:folder_id

Handled by api_delete_folder
Parameters
folder_id string · path
required
Responses
200Successful Response
DELETE /folders/example
1curl -X DELETE "http://localhost:8000/folders/example"
1fetch("http://localhost:8000/folders/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/folders/example")
4print(response.json())
200 Example Response
No Body
DELETE /folders/:folder_id/permissions undocumented

/folders/:folder_id/permissions

Handled by api_revoke_folder_permission
Parameters
folder_id string · path
required
Responses
200Successful Response
DELETE /folders/example/permissions
1curl -X DELETE "http://localhost:8000/folders/example/permissions"
1fetch("http://localhost:8000/folders/example/permissions", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/folders/example/permissions")
4print(response.json())
200 Example Response
No Body
GET /folders undocumented

/folders

Handled by api_list_folders
Responses
200Successful Response
GET /folders
1curl "http://localhost:8000/folders"
1fetch("http://localhost:8000/folders")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/folders")
4print(response.json())
200 Example Response
No Body
GET /folders/:folder_id undocumented

/folders/:folder_id

Handled by api_get_folder
Parameters
folder_id string · path
required
Responses
200Successful Response
GET /folders/example
1curl "http://localhost:8000/folders/example"
1fetch("http://localhost:8000/folders/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/folders/example")
4print(response.json())
200 Example Response
No Body
GET /folders/:folder_id/files undocumented

/folders/:folder_id/files

Handled by api_list_folder_files
Parameters
folder_id string · path
required
Responses
200Successful Response
GET /folders/example/files
1curl "http://localhost:8000/folders/example/files"
1fetch("http://localhost:8000/folders/example/files")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/folders/example/files")
4print(response.json())
200 Example Response
No Body
GET /folders/:folder_id/permissions undocumented

/folders/:folder_id/permissions

Handled by api_list_folder_permissions
Parameters
folder_id string · path
required
Responses
200Successful Response
GET /folders/example/permissions
1curl "http://localhost:8000/folders/example/permissions"
1fetch("http://localhost:8000/folders/example/permissions")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/folders/example/permissions")
4print(response.json())
200 Example Response
No Body
GET /folders/:folder_id/archive undocumented

/folders/:folder_id/archive

GET /folders/:folder_id/archive — the folder tree as a ZIP download.

Handled by api_folder_archive
Parameters
folder_id string · path
required
Responses
200Successful Response
GET /folders/example/archive
1curl "http://localhost:8000/folders/example/archive"
1fetch("http://localhost:8000/folders/example/archive")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/folders/example/archive")
4print(response.json())
200 Example Response
No Body
PATCH /folders/:folder_id

Update a folder

Handled by api_update_folder
Parameters
folder_id string · path
required
Body · UpdateFolderapplication/json
name string · min length: 1 · max length: 255
parent_id string
color string
is_pinned
propertyName anything
Responses
200Successful Response
PATCH /folders/example
1curl -X PATCH "http://localhost:8000/folders/example" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","parent_id":"string","color":"string","is_pinned":null}'
1fetch("http://localhost:8000/folders/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "parent_id": "string",
7 "color": "string",
8 "is_pinned": null
9}),
10})
11 .then((res) => res.json())
12 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/folders/example",
5 json={"name":"string","parent_id":"string","color":"string","is_pinned":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /folders

Create a folder

Handled by api_create_folder
Body · CreateFolderapplication/json
name string · min length: 1 · max length: 255
required
parent_id string
color string
propertyName anything
Responses
200Successful Response
POST /folders
1curl -X POST "http://localhost:8000/folders" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","parent_id":"string","color":"string"}'
1fetch("http://localhost:8000/folders", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "parent_id": "string",
7 "color": "string"
8}),
9})
10 .then((res) => res.json())
11 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/folders",
5 json={"name":"string","parent_id":"string","color":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
DELETE /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.

Handled by api_delete_grant
Parameters
id string · path
required
Responses
200Successful Response
DELETE /grants/example
1curl -X DELETE "http://localhost:8000/grants/example"
1fetch("http://localhost:8000/grants/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/grants/example")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_list_grants
Responses
200Successful Response
GET /grants
1curl "http://localhost:8000/grants"
1fetch("http://localhost:8000/grants")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/grants")
4print(response.json())
200 Example Response
No Body
POST /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.

Handled by api_create_grant
Body · CreateGrantapplication/json
resource_mrn string · min length: 5 · max length: 255
required
principal_type
required
principal_id string · min length: 1 · max length: 100
required
action
required
propertyName anything
Responses
200Successful Response
POST /grants
1curl -X POST "http://localhost:8000/grants" \
2 -H "Content-Type: application/json" \
3 -d '{"resource_mrn":"string","principal_type":null,"principal_id":"string","action":null}'
1fetch("http://localhost:8000/grants", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "resource_mrn": "string",
6 "principal_type": null,
7 "principal_id": "string",
8 "action": null
9}),
10})
11 .then((res) => res.json())
12 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/grants",
5 json={"resource_mrn":"string","principal_type":null,"principal_id":"string","action":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
DELETE /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.

Handled by api_delete_campaign
Parameters
id string · path
required
Responses
200Successful Response
DELETE /growth/campaigns/example
1curl -X DELETE "http://localhost:8000/growth/campaigns/example"
1fetch("http://localhost:8000/growth/campaigns/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/growth/campaigns/example")
4print(response.json())
200 Example Response
No Body
DELETE /growth/goals/:id undocumented

/growth/goals/:id

Handled by api_delete_goal
Parameters
id string · path
required
Responses
200Successful Response
DELETE /growth/goals/example
1curl -X DELETE "http://localhost:8000/growth/goals/example"
1fetch("http://localhost:8000/growth/goals/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/growth/goals/example")
4print(response.json())
200 Example Response
No Body
DELETE /growth/plans/:id undocumented

/growth/plans/:id

Handled by api_delete_plan
Parameters
id string · path
required
Responses
200Successful Response
DELETE /growth/plans/example
1curl -X DELETE "http://localhost:8000/growth/plans/example"
1fetch("http://localhost:8000/growth/plans/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/growth/plans/example")
4print(response.json())
200 Example Response
No Body
DELETE /growth/signals/:id undocumented

/growth/signals/:id

Handled by api_delete_signal
Parameters
id string · path
required
Responses
200Successful Response
DELETE /growth/signals/example
1curl -X DELETE "http://localhost:8000/growth/signals/example"
1fetch("http://localhost:8000/growth/signals/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/growth/signals/example")
4print(response.json())
200 Example Response
No Body
DELETE /growth/attributes/:id undocumented

/growth/attributes/:id

Handled by api_delete_attribute
Parameters
id string · path
required
Responses
200Successful Response
DELETE /growth/attributes/example
1curl -X DELETE "http://localhost:8000/growth/attributes/example"
1fetch("http://localhost:8000/growth/attributes/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/growth/attributes/example")
4print(response.json())
200 Example Response
No Body
DELETE /growth/role-profiles/:id undocumented

/growth/role-profiles/:id

Handled by api_delete_role_profile
Parameters
id string · path
required
Responses
200Successful Response
DELETE /growth/role-profiles/example
1curl -X DELETE "http://localhost:8000/growth/role-profiles/example"
1fetch("http://localhost:8000/growth/role-profiles/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/growth/role-profiles/example")
4print(response.json())
200 Example Response
No Body
DELETE /growth/review-tasks/:id undocumented

/growth/review-tasks/:id

Handled by api_delete_review_task
Parameters
id string · path
required
Responses
200Successful Response
DELETE /growth/review-tasks/example
1curl -X DELETE "http://localhost:8000/growth/review-tasks/example"
1fetch("http://localhost:8000/growth/review-tasks/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/growth/review-tasks/example")
4print(response.json())
200 Example Response
No Body
DELETE /growth/meeting-series/:id undocumented

/growth/meeting-series/:id

Handled by api_delete_meeting_series
Parameters
id string · path
required
Responses
200Successful Response
DELETE /growth/meeting-series/example
1curl -X DELETE "http://localhost:8000/growth/meeting-series/example"
1fetch("http://localhost:8000/growth/meeting-series/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/growth/meeting-series/example")
4print(response.json())
200 Example Response
No Body
GET /growth/campaigns undocumented

/growth/campaigns

Handled by api_list_campaigns
Responses
200Successful Response
GET /growth/campaigns
1curl "http://localhost:8000/growth/campaigns"
1fetch("http://localhost:8000/growth/campaigns")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/growth/campaigns")
4print(response.json())
200 Example Response
No Body
GET /growth/campaigns/:id/results undocumented

/growth/campaigns/:id/results

Aggregated, min-group-size-suppressed engagement results for a campaign.

Handled by api_campaign_results
Parameters
id string · path
required
Responses
200Successful Response
GET /growth/campaigns/example/results
1curl "http://localhost:8000/growth/campaigns/example/results"
1fetch("http://localhost:8000/growth/campaigns/example/results")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/growth/campaigns/example/results")
4print(response.json())
200 Example Response
No Body
GET /growth/goals undocumented

/growth/goals

Handled by api_list_goals
Responses
200Successful Response
GET /growth/goals
1curl "http://localhost:8000/growth/goals"
1fetch("http://localhost:8000/growth/goals")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/growth/goals")
4print(response.json())
200 Example Response
No Body
GET /growth/goals/summary undocumented

/growth/goals/summary

Handled by api_goals_summary
Responses
200Successful Response
GET /growth/goals/summary
1curl "http://localhost:8000/growth/goals/summary"
1fetch("http://localhost:8000/growth/goals/summary")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/growth/goals/summary")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_get_goal
Parameters
id string · path
required
Responses
200Successful Response
GET /growth/goals/example
1curl "http://localhost:8000/growth/goals/example"
1fetch("http://localhost:8000/growth/goals/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/growth/goals/example")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_list_goal_comments
Parameters
id string · path
required
Responses
200Successful Response
GET /growth/goals/example/comments
1curl "http://localhost:8000/growth/goals/example/comments"
1fetch("http://localhost:8000/growth/goals/example/comments")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/growth/goals/example/comments")
4print(response.json())
200 Example Response
No Body
GET /growth/plans undocumented

/growth/plans

Handled by api_list_plans
Responses
200Successful Response
GET /growth/plans
1curl "http://localhost:8000/growth/plans"
1fetch("http://localhost:8000/growth/plans")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/growth/plans")
4print(response.json())
200 Example Response
No Body
GET /growth/signals undocumented

/growth/signals

Handled by api_list_signals
Responses
200Successful Response
GET /growth/signals
1curl "http://localhost:8000/growth/signals"
1fetch("http://localhost:8000/growth/signals")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/growth/signals")
4print(response.json())
200 Example Response
No Body
GET /growth/signals/:id undocumented

/growth/signals/:id

One signal. The full-page 1:1 view loads an interaction through here.

Handled by api_get_signal
Parameters
id string · path
required
Responses
200Successful Response
GET /growth/signals/example
1curl "http://localhost:8000/growth/signals/example"
1fetch("http://localhost:8000/growth/signals/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/growth/signals/example")
4print(response.json())
200 Example Response
No Body
GET /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).

Handled by api_list_promoted_tasks
Parameters
id string · path
required
Responses
200Successful Response
GET /growth/signals/example/action-items/tasks
1curl "http://localhost:8000/growth/signals/example/action-items/tasks"
1fetch("http://localhost:8000/growth/signals/example/action-items/tasks")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/growth/signals/example/action-items/tasks")
4print(response.json())
200 Example Response
No Body
GET /growth/attributes undocumented

/growth/attributes

Handled by api_list_attributes
Responses
200Successful Response
GET /growth/attributes
1curl "http://localhost:8000/growth/attributes"
1fetch("http://localhost:8000/growth/attributes")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/growth/attributes")
4print(response.json())
200 Example Response
No Body
GET /growth/role-profiles undocumented

/growth/role-profiles

Handled by api_list_role_profiles
Responses
200Successful Response
GET /growth/role-profiles
1curl "http://localhost:8000/growth/role-profiles"
1fetch("http://localhost:8000/growth/role-profiles")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/growth/role-profiles")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_get_role_profile
Parameters
id string · path
required
Responses
200Successful Response
GET /growth/role-profiles/example
1curl "http://localhost:8000/growth/role-profiles/example"
1fetch("http://localhost:8000/growth/role-profiles/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/growth/role-profiles/example")
4print(response.json())
200 Example Response
No Body
GET /growth/review-tasks undocumented

/growth/review-tasks

Handled by api_list_review_tasks
Responses
200Successful Response
GET /growth/review-tasks
1curl "http://localhost:8000/growth/review-tasks"
1fetch("http://localhost:8000/growth/review-tasks")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/growth/review-tasks")
4print(response.json())
200 Example Response
No Body
GET /growth/meeting-series undocumented

/growth/meeting-series

Handled by api_list_meeting_series
Responses
200Successful Response
GET /growth/meeting-series
1curl "http://localhost:8000/growth/meeting-series"
1fetch("http://localhost:8000/growth/meeting-series")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/growth/meeting-series")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_skill_matrix
Responses
200Successful Response
GET /growth/skill-matrix
1curl "http://localhost:8000/growth/skill-matrix"
1fetch("http://localhost:8000/growth/skill-matrix")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/growth/skill-matrix")
4print(response.json())
200 Example Response
No Body
GET /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).

Handled by api_list_concerns
Responses
200Successful Response
GET /growth/concerns
1curl "http://localhost:8000/growth/concerns"
1fetch("http://localhost:8000/growth/concerns")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/growth/concerns")
4print(response.json())
200 Example Response
No Body
GET /growth/overview undocumented

/growth/overview

Handled by api_overview
Responses
200Successful Response
GET /growth/overview
1curl "http://localhost:8000/growth/overview"
1fetch("http://localhost:8000/growth/overview")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/growth/overview")
4print(response.json())
200 Example Response
No Body
GET /growth/workers undocumented

/growth/workers

The people growth knows as workers, named by their worker record.

Handled by api_list_workers
Responses
200Successful Response
GET /growth/workers
1curl "http://localhost:8000/growth/workers"
1fetch("http://localhost:8000/growth/workers")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/growth/workers")
4print(response.json())
200 Example Response
No Body
GET /growth/reports undocumented

/growth/reports

GET /growth/reports: the caller's direct reports, by name.

Handled by api_list_reports
Responses
200Successful Response
GET /growth/reports
1curl "http://localhost:8000/growth/reports"
1fetch("http://localhost:8000/growth/reports")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/growth/reports")
4print(response.json())
200 Example Response
No Body
GET /growth/people/:member_id undocumented

/growth/people/:member_id

GET /growth/people/:member_id: who someone is and how the caller relates to them.

Handled by api_get_person
Parameters
member_id string · path
required
Responses
200Successful Response
GET /growth/people/example
1curl "http://localhost:8000/growth/people/example"
1fetch("http://localhost:8000/growth/people/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/growth/people/example")
4print(response.json())
200 Example Response
No Body
GET /growth/people undocumented

/growth/people

GET /growth/people?members=mrn,mrn: what the caller may see about each person on one page.

Handled by api_list_people
Responses
200Successful Response
GET /growth/people
1curl "http://localhost:8000/growth/people"
1fetch("http://localhost:8000/growth/people")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/growth/people")
4print(response.json())
200 Example Response
No Body
POST /growth/campaigns

Create a survey

Handled by api_create_campaign
Body · CreateCampaignapplication/json
title string · min length: 1 · max length: 120
required
kind
frequency
drivers array
custom_questions array
question_ids array
review_kinds array
enps
comment
starts_at string
ends_at string
propertyName anything
Responses
200Successful Response
POST /growth/campaigns
1curl -X POST "http://localhost:8000/growth/campaigns" \
2 -H "Content-Type: application/json" \
3 -d '{"title":"string","kind":null,"frequency":null,"drivers":[null],"custom_questions":[{"label":"string","html":"string"}],"question_ids":["string"],"review_kinds":[null],"enps":null,"comment":null,"starts_at":"string","ends_at":"string"}'
1fetch("http://localhost:8000/growth/campaigns", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "title": "string",
6 "kind": null,
7 "frequency": null,
8 "drivers": [
9 null
10 ],
11 "custom_questions": [
12 {
13 "label": "string",
14 "html": "string"
15 }
16 ],
17 "question_ids": [
18 "string"
19 ],
20 "review_kinds": [
21 null
22 ],
23 "enps": null,
24 "comment": null,
25 "starts_at": "string",
26 "ends_at": "string"
27}),
28})
29 .then((res) => res.json())
30 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/growth/campaigns",
5 json={"title":"string","kind":null,"frequency":null,"drivers":[null],"custom_questions":[{"label":"string","html":"string"}],"question_ids":["string"],"review_kinds":[null],"enps":null,"comment":null,"starts_at":"string","ends_at":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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.

Handled by api_submit_response
Body · SubmitResponseapplication/json
campaign_id string · min length: 1
required
scores object
custom_scores array
enps integer · min: 0 · max: 10
comment string · max length: 2000
propertyName anything
Responses
200Successful Response
POST /growth/responses
1curl -X POST "http://localhost:8000/growth/responses" \
2 -H "Content-Type: application/json" \
3 -d '{"campaign_id":"string","scores":{"recognition":1,"workload":1,"growth":1,"autonomy":1,"belonging":1,"management":1,"purpose":1,"voice":1},"custom_scores":[1],"enps":1,"comment":"string"}'
1fetch("http://localhost:8000/growth/responses", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "campaign_id": "string",
6 "scores": {
7 "recognition": 1,
8 "workload": 1,
9 "growth": 1,
10 "autonomy": 1,
11 "belonging": 1,
12 "management": 1,
13 "purpose": 1,
14 "voice": 1
15 },
16 "custom_scores": [
17 1
18 ],
19 "enps": 1,
20 "comment": "string"
21}),
22})
23 .then((res) => res.json())
24 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/growth/responses",
5 json={"campaign_id":"string","scores":{"recognition":1,"workload":1,"growth":1,"autonomy":1,"belonging":1,"management":1,"purpose":1,"voice":1},"custom_scores":[1],"enps":1,"comment":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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.

Handled by api_reply
Parameters
id string · path
required
Body · ReplyToCommentapplication/json
body string · min length: 1 · max length: 2000
required
propertyName anything
Responses
200Successful Response
POST /growth/responses/example/replies
1curl -X POST "http://localhost:8000/growth/responses/example/replies" \
2 -H "Content-Type: application/json" \
3 -d '{"body":"string"}'
1fetch("http://localhost:8000/growth/responses/example/replies", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "body": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/growth/responses/example/replies",
5 json={"body":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /growth/goals

Create a goal, KR or KPI

Handled by api_create_goal
Body · CreateGoalapplication/json
title string · min length: 1 · max length: 200
required
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
Responses
200Successful Response
POST /growth/goals
1curl -X POST "http://localhost:8000/growth/goals" \
2 -H "Content-Type: application/json" \
3 -d '{"title":"string","kind":null,"scope":null,"key_results":[{"title":"string","metric":"string","start_value":1.5,"target_value":1.5,"unit":"string"}],"subject_mrn":"string","owner_mrn":"string","parent_id":"string","target":{"metric":"string","start_value":1.5,"target_value":1.5,"unit":"string","direction":null},"metric":"string","start_value":1.5,"target_value":1.5,"unit":"string","direction":null,"period":"string","starts_at":"string","due_at":"string"}'
1fetch("http://localhost:8000/growth/goals", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "title": "string",
6 "kind": null,
7 "scope": null,
8 "key_results": [
9 {
10 "title": "string",
11 "metric": "string",
12 "start_value": 1.5,
13 "target_value": 1.5,
14 "unit": "string"
15 }
16 ],
17 "subject_mrn": "string",
18 "owner_mrn": "string",
19 "parent_id": "string",
20 "target": {
21 "metric": "string",
22 "start_value": 1.5,
23 "target_value": 1.5,
24 "unit": "string",
25 "direction": null
26 },
27 "metric": "string",
28 "start_value": 1.5,
29 "target_value": 1.5,
30 "unit": "string",
31 "direction": null,
32 "period": "string",
33 "starts_at": "string",
34 "due_at": "string"
35}),
36})
37 .then((res) => res.json())
38 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/growth/goals",
5 json={"title":"string","kind":null,"scope":null,"key_results":[{"title":"string","metric":"string","start_value":1.5,"target_value":1.5,"unit":"string"}],"subject_mrn":"string","owner_mrn":"string","parent_id":"string","target":{"metric":"string","start_value":1.5,"target_value":1.5,"unit":"string","direction":null},"metric":"string","start_value":1.5,"target_value":1.5,"unit":"string","direction":null,"period":"string","starts_at":"string","due_at":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /growth/goals/:id/progress

Log goal progress

Handled by api_log_goal_progress
Parameters
id string · path
required
Body · LogGoalProgressapplication/json
value number
required
note string · max length: 500
propertyName anything
Responses
200Successful Response
POST /growth/goals/example/progress
1curl -X POST "http://localhost:8000/growth/goals/example/progress" \
2 -H "Content-Type: application/json" \
3 -d '{"value":1.5,"note":"string"}'
1fetch("http://localhost:8000/growth/goals/example/progress", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "value": 1.5,
6 "note": "string"
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/growth/goals/example/progress",
5 json={"value":1.5,"note":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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.

Handled by api_create_goal_comment
Parameters
id string · path
required
Body · CreateGoalCommentapplication/json
text string · min length: 1 · max length: 4000
required
propertyName anything
Responses
200Successful Response
POST /growth/goals/example/comments
1curl -X POST "http://localhost:8000/growth/goals/example/comments" \
2 -H "Content-Type: application/json" \
3 -d '{"text":"string"}'
1fetch("http://localhost:8000/growth/goals/example/comments", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "text": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/growth/goals/example/comments",
5 json={"text":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /growth/plans

Create a development plan or PIP

Handled by api_create_plan
Body · CreatePlanapplication/json
title string · min length: 1 · max length: 200
required
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
Responses
200Successful Response
POST /growth/plans
1curl -X POST "http://localhost:8000/growth/plans" \
2 -H "Content-Type: application/json" \
3 -d '{"title":"string","kind":null,"subject_type":null,"subject_mrn":"string","owner_mrn":"string","reason":"string","detail":{"milestones":[{"title":"string","done":null,"due_at":"string"}],"notes":"string","goal_ids":["string"],"driver":"string","campaign_id":"string","outcome":"string"},"milestones":["string"],"starts_at":"string","ends_at":"string"}'
1fetch("http://localhost:8000/growth/plans", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "title": "string",
6 "kind": null,
7 "subject_type": null,
8 "subject_mrn": "string",
9 "owner_mrn": "string",
10 "reason": "string",
11 "detail": {
12 "milestones": [
13 {
14 "title": "string",
15 "done": null,
16 "due_at": "string"
17 }
18 ],
19 "notes": "string",
20 "goal_ids": [
21 "string"
22 ],
23 "driver": "string",
24 "campaign_id": "string",
25 "outcome": "string"
26 },
27 "milestones": [
28 "string"
29 ],
30 "starts_at": "string",
31 "ends_at": "string"
32}),
33})
34 .then((res) => res.json())
35 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/growth/plans",
5 json={"title":"string","kind":null,"subject_type":null,"subject_mrn":"string","owner_mrn":"string","reason":"string","detail":{"milestones":[{"title":"string","done":null,"due_at":"string"}],"notes":"string","goal_ids":["string"],"driver":"string","campaign_id":"string","outcome":"string"},"milestones":["string"],"starts_at":"string","ends_at":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /growth/signals

Give feedback, praise, a 1:1 note or review

Handled by api_create_signal
Body · CreateSignalapplication/json
kind
required
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
Responses
200Successful Response
POST /growth/signals
1curl -X POST "http://localhost:8000/growth/signals" \
2 -H "Content-Type: application/json" \
3 -d '{"kind":null,"subject_mrn":"string","campaign_id":"string","parent_id":"string","series_id":"string","visibility":null,"body":{"title":"string","text":"string","competencies":["string"],"competency_ratings":[{"attribute_id":"string","level":1}],"values":["string"],"agenda":[null],"action_items":[null],"check_in_items":[{"text":"string","done":null,"added_at":"string"}],"private_notes":[{"author_mrn":"string","text":"string"}]},"title":"string","text":"string","values":["string"],"competencies":["string"],"competency_ratings":[{"attribute_id":"string","level":1}],"agenda":[null],"action_items":[null],"check_in_items":[{"text":"string","done":null,"added_at":"string"}],"private_note":"string","rating":1.5,"occurred_at":"string"}'
1fetch("http://localhost:8000/growth/signals", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "kind": null,
6 "subject_mrn": "string",
7 "campaign_id": "string",
8 "parent_id": "string",
9 "series_id": "string",
10 "visibility": null,
11 "body": {
12 "title": "string",
13 "text": "string",
14 "competencies": [
15 "string"
16 ],
17 "competency_ratings": [
18 {
19 "attribute_id": "string",
20 "level": 1
21 }
22 ],
23 "values": [
24 "string"
25 ],
26 "agenda": [
27 null
28 ],
29 "action_items": [
30 null
31 ],
32 "check_in_items": [
33 {
34 "text": "string",
35 "done": null,
36 "added_at": "string"
37 }
38 ],
39 "private_notes": [
40 {
41 "author_mrn": "string",
42 "text": "string"
43 }
44 ]
45 },
46 "title": "string",
47 "text": "string",
48 "values": [
49 "string"
50 ],
51 "competencies": [
52 "string"
53 ],
54 "competency_ratings": [
55 {
56 "attribute_id": "string",
57 "level": 1
58 }
59 ],
60 "agenda": [
61 null
62 ],
63 "action_items": [
64 null
65 ],
66 "check_in_items": [
67 {
68 "text": "string",
69 "done": null,
70 "added_at": "string"
71 }
72 ],
73 "private_note": "string",
74 "rating": 1.5,
75 "occurred_at": "string"
76}),
77})
78 .then((res) => res.json())
79 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/growth/signals",
5 json={"kind":null,"subject_mrn":"string","campaign_id":"string","parent_id":"string","series_id":"string","visibility":null,"body":{"title":"string","text":"string","competencies":["string"],"competency_ratings":[{"attribute_id":"string","level":1}],"values":["string"],"agenda":[null],"action_items":[null],"check_in_items":[{"text":"string","done":null,"added_at":"string"}],"private_notes":[{"author_mrn":"string","text":"string"}]},"title":"string","text":"string","values":["string"],"competencies":["string"],"competency_ratings":[{"attribute_id":"string","level":1}],"agenda":[null],"action_items":[null],"check_in_items":[{"text":"string","done":null,"added_at":"string"}],"private_note":"string","rating":1.5,"occurred_at":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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.

Handled by api_promote_action_item
Parameters
id string · path
required
index string · path
required
Body · PromoteActionItemapplication/json
board_id string · min length: 1
required
propertyName anything
Responses
200Successful Response
POST /growth/signals/example/action-items/example/task
1curl -X POST "http://localhost:8000/growth/signals/example/action-items/example/task" \
2 -H "Content-Type: application/json" \
3 -d '{"board_id":"string"}'
1fetch("http://localhost:8000/growth/signals/example/action-items/example/task", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "board_id": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/growth/signals/example/action-items/example/task",
5 json={"board_id":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /growth/attributes

Create a competency, value or bank question

Handled by api_create_attribute
Body · CreateAttributeapplication/json
kind
required
name string · min length: 1 · max length: 120
required
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
Responses
200Successful Response
POST /growth/attributes
1curl -X POST "http://localhost:8000/growth/attributes" \
2 -H "Content-Type: application/json" \
3 -d '{"kind":null,"name":"string","description":"string","category":"string","levels":[{"level":1,"name":"string","description":"string"}],"driver":null,"scale":1,"sort":1}'
1fetch("http://localhost:8000/growth/attributes", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "kind": null,
6 "name": "string",
7 "description": "string",
8 "category": "string",
9 "levels": [
10 {
11 "level": 1,
12 "name": "string",
13 "description": "string"
14 }
15 ],
16 "driver": null,
17 "scale": 1,
18 "sort": 1
19}),
20})
21 .then((res) => res.json())
22 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/growth/attributes",
5 json={"kind":null,"name":"string","description":"string","category":"string","levels":[{"level":1,"name":"string","description":"string"}],"driver":null,"scale":1,"sort":1},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /growth/role-profiles

Create a role profile

Handled by api_create_role_profile
Body · CreateRoleProfileapplication/json
title string · min length: 1 · max length: 120
required
track string · max length: 80
level string · max length: 40
description string · max length: 2000
expectations array
job_titles array
propertyName anything
Responses
200Successful Response
POST /growth/role-profiles
1curl -X POST "http://localhost:8000/growth/role-profiles" \
2 -H "Content-Type: application/json" \
3 -d '{"title":"string","track":"string","level":"string","description":"string","expectations":[{"attribute_id":"string","level":1}],"job_titles":["string"]}'
1fetch("http://localhost:8000/growth/role-profiles", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "title": "string",
6 "track": "string",
7 "level": "string",
8 "description": "string",
9 "expectations": [
10 {
11 "attribute_id": "string",
12 "level": 1
13 }
14 ],
15 "job_titles": [
16 "string"
17 ]
18}),
19})
20 .then((res) => res.json())
21 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/growth/role-profiles",
5 json={"title":"string","track":"string","level":"string","description":"string","expectations":[{"attribute_id":"string","level":1}],"job_titles":["string"]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /growth/review-tasks

Nominate a peer or upward reviewer

Peer / upward nomination. Self and manager tasks come from cycle launch.

Handled by api_create_review_task
Body · CreateReviewTaskapplication/json
campaign_id string · min length: 1 · max length: 80
required
kind
reviewer_mrn string · min length: 1 · max length: 200
required
subject_mrn string · max length: 200
due_at string
propertyName anything
Responses
200Successful Response
POST /growth/review-tasks
1curl -X POST "http://localhost:8000/growth/review-tasks" \
2 -H "Content-Type: application/json" \
3 -d '{"campaign_id":"string","kind":null,"reviewer_mrn":"string","subject_mrn":"string","due_at":"string"}'
1fetch("http://localhost:8000/growth/review-tasks", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "campaign_id": "string",
6 "kind": null,
7 "reviewer_mrn": "string",
8 "subject_mrn": "string",
9 "due_at": "string"
10}),
11})
12 .then((res) => res.json())
13 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/growth/review-tasks",
5 json={"campaign_id":"string","kind":null,"reviewer_mrn":"string","subject_mrn":"string","due_at":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /growth/meeting-series

Start a recurring 1:1

Handled by api_create_meeting_series
Body · CreateMeetingSeriesapplication/json
participant_mrn string · min length: 1 · max length: 200
required
title string · max length: 120
cadence
next_at string
agenda array
propertyName anything
Responses
200Successful Response
POST /growth/meeting-series
1curl -X POST "http://localhost:8000/growth/meeting-series" \
2 -H "Content-Type: application/json" \
3 -d '{"participant_mrn":"string","title":"string","cadence":null,"next_at":"string","agenda":["string"]}'
1fetch("http://localhost:8000/growth/meeting-series", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "participant_mrn": "string",
6 "title": "string",
7 "cadence": null,
8 "next_at": "string",
9 "agenda": [
10 "string"
11 ]
12}),
13})
14 .then((res) => res.json())
15 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/growth/meeting-series",
5 json={"participant_mrn":"string","title":"string","cadence":null,"next_at":"string","agenda":["string"]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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.

Handled by api_create_concern
Body · CreateConcernapplication/json
body string · min length: 1 · max length: 4000
required
anonymous
propertyName anything
Responses
200Successful Response
POST /growth/concerns
1curl -X POST "http://localhost:8000/growth/concerns" \
2 -H "Content-Type: application/json" \
3 -d '{"body":"string","anonymous":null}'
1fetch("http://localhost:8000/growth/concerns", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "body": "string",
6 "anonymous": null
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/growth/concerns",
5 json={"body":"string","anonymous":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /growth/campaigns/:id

Update or launch a survey

Handled by api_update_campaign
Parameters
id string · path
required
Body · UpdateCampaignapplication/json
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
Responses
200Successful Response
PUT /growth/campaigns/example
1curl -X PUT "http://localhost:8000/growth/campaigns/example" \
2 -H "Content-Type: application/json" \
3 -d '{"title":"string","status":null,"frequency":null,"drivers":[null],"custom_questions":[{"label":"string","html":"string"}],"question_ids":["string"],"review_kinds":[null],"enps":null,"comment":null,"starts_at":"string","ends_at":"string"}'
1fetch("http://localhost:8000/growth/campaigns/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "title": "string",
6 "status": null,
7 "frequency": null,
8 "drivers": [
9 null
10 ],
11 "custom_questions": [
12 {
13 "label": "string",
14 "html": "string"
15 }
16 ],
17 "question_ids": [
18 "string"
19 ],
20 "review_kinds": [
21 null
22 ],
23 "enps": null,
24 "comment": null,
25 "starts_at": "string",
26 "ends_at": "string"
27}),
28})
29 .then((res) => res.json())
30 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/growth/campaigns/example",
5 json={"title":"string","status":null,"frequency":null,"drivers":[null],"custom_questions":[{"label":"string","html":"string"}],"question_ids":["string"],"review_kinds":[null],"enps":null,"comment":null,"starts_at":"string","ends_at":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /growth/goals/:id

Update a goal

Handled by api_update_goal
Parameters
id string · path
required
Body · UpdateGoalapplication/json
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
Responses
200Successful Response
PUT /growth/goals/example
1curl -X PUT "http://localhost:8000/growth/goals/example" \
2 -H "Content-Type: application/json" \
3 -d '{"title":"string","status":null,"owner_mrn":"string","parent_id":"string","target":{"metric":"string","start_value":1.5,"target_value":1.5,"unit":"string","direction":null},"period":"string","due_at":"string"}'
1fetch("http://localhost:8000/growth/goals/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "title": "string",
6 "status": null,
7 "owner_mrn": "string",
8 "parent_id": "string",
9 "target": {
10 "metric": "string",
11 "start_value": 1.5,
12 "target_value": 1.5,
13 "unit": "string",
14 "direction": null
15 },
16 "period": "string",
17 "due_at": "string"
18}),
19})
20 .then((res) => res.json())
21 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/growth/goals/example",
5 json={"title":"string","status":null,"owner_mrn":"string","parent_id":"string","target":{"metric":"string","start_value":1.5,"target_value":1.5,"unit":"string","direction":null},"period":"string","due_at":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /growth/plans/:id

Update a plan

Handled by api_update_plan
Parameters
id string · path
required
Body · UpdatePlanapplication/json
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
Responses
200Successful Response
PUT /growth/plans/example
1curl -X PUT "http://localhost:8000/growth/plans/example" \
2 -H "Content-Type: application/json" \
3 -d '{"title":"string","status":null,"owner_mrn":"string","reason":"string","detail":{"milestones":[{"title":"string","done":null,"due_at":"string"}],"notes":"string","goal_ids":["string"],"driver":"string","campaign_id":"string","outcome":"string"},"starts_at":"string","ends_at":"string"}'
1fetch("http://localhost:8000/growth/plans/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "title": "string",
6 "status": null,
7 "owner_mrn": "string",
8 "reason": "string",
9 "detail": {
10 "milestones": [
11 {
12 "title": "string",
13 "done": null,
14 "due_at": "string"
15 }
16 ],
17 "notes": "string",
18 "goal_ids": [
19 "string"
20 ],
21 "driver": "string",
22 "campaign_id": "string",
23 "outcome": "string"
24 },
25 "starts_at": "string",
26 "ends_at": "string"
27}),
28})
29 .then((res) => res.json())
30 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/growth/plans/example",
5 json={"title":"string","status":null,"owner_mrn":"string","reason":"string","detail":{"milestones":[{"title":"string","done":null,"due_at":"string"}],"notes":"string","goal_ids":["string"],"driver":"string","campaign_id":"string","outcome":"string"},"starts_at":"string","ends_at":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /growth/signals/:id

Update a signal

Handled by api_update_signal
Parameters
id string · path
required
Body · UpdateSignalapplication/json
visibility
body object
rating number · min: 0 · max: 5
status
series_id string · max length: 80
private_note string · max length: 8000
propertyName anything
Responses
200Successful Response
PUT /growth/signals/example
1curl -X PUT "http://localhost:8000/growth/signals/example" \
2 -H "Content-Type: application/json" \
3 -d '{"visibility":null,"body":{"title":"string","text":"string","competencies":["string"],"competency_ratings":[{"attribute_id":"string","level":1}],"values":["string"],"agenda":[null],"action_items":[null],"check_in_items":[{"text":"string","done":null,"added_at":"string"}],"private_notes":[{"author_mrn":"string","text":"string"}]},"rating":1.5,"status":null,"series_id":"string","private_note":"string"}'
1fetch("http://localhost:8000/growth/signals/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "visibility": null,
6 "body": {
7 "title": "string",
8 "text": "string",
9 "competencies": [
10 "string"
11 ],
12 "competency_ratings": [
13 {
14 "attribute_id": "string",
15 "level": 1
16 }
17 ],
18 "values": [
19 "string"
20 ],
21 "agenda": [
22 null
23 ],
24 "action_items": [
25 null
26 ],
27 "check_in_items": [
28 {
29 "text": "string",
30 "done": null,
31 "added_at": "string"
32 }
33 ],
34 "private_notes": [
35 {
36 "author_mrn": "string",
37 "text": "string"
38 }
39 ]
40 },
41 "rating": 1.5,
42 "status": null,
43 "series_id": "string",
44 "private_note": "string"
45}),
46})
47 .then((res) => res.json())
48 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/growth/signals/example",
5 json={"visibility":null,"body":{"title":"string","text":"string","competencies":["string"],"competency_ratings":[{"attribute_id":"string","level":1}],"values":["string"],"agenda":[null],"action_items":[null],"check_in_items":[{"text":"string","done":null,"added_at":"string"}],"private_notes":[{"author_mrn":"string","text":"string"}]},"rating":1.5,"status":null,"series_id":"string","private_note":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /growth/attributes/:id

Update a competency, value or question

Handled by api_update_attribute
Parameters
id string · path
required
Body · UpdateAttributeapplication/json
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
Responses
200Successful Response
PUT /growth/attributes/example
1curl -X PUT "http://localhost:8000/growth/attributes/example" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","description":"string","category":"string","levels":[{"level":1,"name":"string","description":"string"}],"driver":null,"scale":1,"sort":1,"status":null}'
1fetch("http://localhost:8000/growth/attributes/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "description": "string",
7 "category": "string",
8 "levels": [
9 {
10 "level": 1,
11 "name": "string",
12 "description": "string"
13 }
14 ],
15 "driver": null,
16 "scale": 1,
17 "sort": 1,
18 "status": null
19}),
20})
21 .then((res) => res.json())
22 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/growth/attributes/example",
5 json={"name":"string","description":"string","category":"string","levels":[{"level":1,"name":"string","description":"string"}],"driver":null,"scale":1,"sort":1,"status":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /growth/role-profiles/:id

Update a role profile

Handled by api_update_role_profile
Parameters
id string · path
required
Body · UpdateRoleProfileapplication/json
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
Responses
200Successful Response
PUT /growth/role-profiles/example
1curl -X PUT "http://localhost:8000/growth/role-profiles/example" \
2 -H "Content-Type: application/json" \
3 -d '{"title":"string","track":"string","level":"string","description":"string","expectations":[{"attribute_id":"string","level":1}],"job_titles":["string"],"matrix":{"levels":[{"key":"string","label":"string"}],"cells":[{"attribute_id":"string","level_key":"string","text":"string","format":{"bold":null,"italic":null,"underline":null,"color":"string","background":"string","align":null}}],"columns":[{"level_key":"string","width":1}]},"status":null}'
1fetch("http://localhost:8000/growth/role-profiles/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "title": "string",
6 "track": "string",
7 "level": "string",
8 "description": "string",
9 "expectations": [
10 {
11 "attribute_id": "string",
12 "level": 1
13 }
14 ],
15 "job_titles": [
16 "string"
17 ],
18 "matrix": {
19 "levels": [
20 {
21 "key": "string",
22 "label": "string"
23 }
24 ],
25 "cells": [
26 {
27 "attribute_id": "string",
28 "level_key": "string",
29 "text": "string",
30 "format": {
31 "bold": null,
32 "italic": null,
33 "underline": null,
34 "color": "string",
35 "background": "string",
36 "align": null
37 }
38 }
39 ],
40 "columns": [
41 {
42 "level_key": "string",
43 "width": 1
44 }
45 ]
46 },
47 "status": null
48}),
49})
50 .then((res) => res.json())
51 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/growth/role-profiles/example",
5 json={"title":"string","track":"string","level":"string","description":"string","expectations":[{"attribute_id":"string","level":1}],"job_titles":["string"],"matrix":{"levels":[{"key":"string","label":"string"}],"cells":[{"attribute_id":"string","level_key":"string","text":"string","format":{"bold":null,"italic":null,"underline":null,"color":"string","background":"string","align":null}}],"columns":[{"level_key":"string","width":1}]},"status":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /growth/review-tasks/:id

Update a review task

Handled by api_update_review_task
Parameters
id string · path
required
Body · UpdateReviewTaskapplication/json
status
due_at string
extension_until string
extension_note string · max length: 500
extension
propertyName anything
Responses
200Successful Response
PUT /growth/review-tasks/example
1curl -X PUT "http://localhost:8000/growth/review-tasks/example" \
2 -H "Content-Type: application/json" \
3 -d '{"status":null,"due_at":"string","extension_until":"string","extension_note":"string","extension":null}'
1fetch("http://localhost:8000/growth/review-tasks/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "status": null,
6 "due_at": "string",
7 "extension_until": "string",
8 "extension_note": "string",
9 "extension": null
10}),
11})
12 .then((res) => res.json())
13 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/growth/review-tasks/example",
5 json={"status":null,"due_at":"string","extension_until":"string","extension_note":"string","extension":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /growth/meeting-series/:id

Update a 1:1 series

Handled by api_update_meeting_series
Parameters
id string · path
required
Body · UpdateMeetingSeriesapplication/json
title string · max length: 120
cadence
next_at string
agenda array
status
propertyName anything
Responses
200Successful Response
PUT /growth/meeting-series/example
1curl -X PUT "http://localhost:8000/growth/meeting-series/example" \
2 -H "Content-Type: application/json" \
3 -d '{"title":"string","cadence":null,"next_at":"string","agenda":[{"text":"string","kind":null,"done":null,"added_at":"string"}],"status":null}'
1fetch("http://localhost:8000/growth/meeting-series/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "title": "string",
6 "cadence": null,
7 "next_at": "string",
8 "agenda": [
9 {
10 "text": "string",
11 "kind": null,
12 "done": null,
13 "added_at": "string"
14 }
15 ],
16 "status": null
17}),
18})
19 .then((res) => res.json())
20 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/growth/meeting-series/example",
5 json={"title":"string","cadence":null,"next_at":"string","agenda":[{"text":"string","kind":null,"done":null,"added_at":"string"}],"status":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
GET /health undocumented

/health

Handled by health
Responses
200Successful Response
GET /health
1curl "http://localhost:8000/health"
1fetch("http://localhost:8000/health")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/health")
4print(response.json())
200 Example Response
No Body
DELETE /holidays/:id undocumented

/holidays/:id

Handled by api_delete_holiday
Parameters
id string · path
required
Responses
200Successful Response
DELETE /holidays/example
1curl -X DELETE "http://localhost:8000/holidays/example"
1fetch("http://localhost:8000/holidays/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/holidays/example")
4print(response.json())
200 Example Response
No Body
GET /holidays undocumented

/holidays

Handled by api_list_holidays
Responses
200Successful Response
GET /holidays
1curl "http://localhost:8000/holidays"
1fetch("http://localhost:8000/holidays")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/holidays")
4print(response.json())
200 Example Response
No Body
POST /holidays

Create a holiday

Handled by api_create_holiday
Body · CreateHolidayapplication/json
name string · min length: 1 · max length: 100
required
date string · min length: 1
required
is_recurring
propertyName anything
Responses
200Successful Response
POST /holidays
1curl -X POST "http://localhost:8000/holidays" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","date":"string","is_recurring":null}'
1fetch("http://localhost:8000/holidays", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "date": "string",
7 "is_recurring": null
8}),
9})
10 .then((res) => res.json())
11 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/holidays",
5 json={"name":"string","date":"string","is_recurring":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /holidays/:id

Update a holiday

Handled by api_update_holiday
Parameters
id string · path
required
Body · UpdateHolidayapplication/json
name string · min length: 1 · max length: 100
date string · min length: 1
is_recurring
propertyName anything
Responses
200Successful Response
PUT /holidays/example
1curl -X PUT "http://localhost:8000/holidays/example" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","date":"string","is_recurring":null}'
1fetch("http://localhost:8000/holidays/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "date": "string",
7 "is_recurring": null
8}),
9})
10 .then((res) => res.json())
11 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/holidays/example",
5 json={"name":"string","date":"string","is_recurring":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
DELETE /hub/posts/:id undocumented

/hub/posts/:id

DELETE /hub/posts/:id: the author, or an owner or admin.

Handled by api_delete_post
Parameters
id string · path
required
Responses
200Successful Response
DELETE /hub/posts/example
1curl -X DELETE "http://localhost:8000/hub/posts/example"
1fetch("http://localhost:8000/hub/posts/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/hub/posts/example")
4print(response.json())
200 Example Response
No Body
DELETE /hub/posts/:id/reactions undocumented

/hub/posts/:id/reactions

DELETE /hub/posts/:id/reactions: take yours back.

Handled by api_unreact
Parameters
id string · path
required
Responses
200Successful Response
DELETE /hub/posts/example/reactions
1curl -X DELETE "http://localhost:8000/hub/posts/example/reactions"
1fetch("http://localhost:8000/hub/posts/example/reactions", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/hub/posts/example/reactions")
4print(response.json())
200 Example Response
No Body
DELETE /hub/posts/:id/reposts undocumented

/hub/posts/:id/reposts

DELETE /hub/posts/:id/reposts: undo your plain repost of this post.

Handled by api_unrepost
Parameters
id string · path
required
Responses
200Successful Response
DELETE /hub/posts/example/reposts
1curl -X DELETE "http://localhost:8000/hub/posts/example/reposts"
1fetch("http://localhost:8000/hub/posts/example/reposts", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/hub/posts/example/reposts")
4print(response.json())
200 Example Response
No Body
DELETE /hub/posts/:id/votes undocumented

/hub/posts/:id/votes

DELETE /hub/posts/:id/votes: take your vote back.

Handled by api_unvote
Parameters
id string · path
required
Responses
200Successful Response
DELETE /hub/posts/example/votes
1curl -X DELETE "http://localhost:8000/hub/posts/example/votes"
1fetch("http://localhost:8000/hub/posts/example/votes", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/hub/posts/example/votes")
4print(response.json())
200 Example Response
No Body
DELETE /hub/posts/:id/bookmarks undocumented

/hub/posts/:id/bookmarks

DELETE /hub/posts/:id/bookmarks

Handled by api_unbookmark
Parameters
id string · path
required
Responses
200Successful Response
DELETE /hub/posts/example/bookmarks
1curl -X DELETE "http://localhost:8000/hub/posts/example/bookmarks"
1fetch("http://localhost:8000/hub/posts/example/bookmarks", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/hub/posts/example/bookmarks")
4print(response.json())
200 Example Response
No Body
DELETE /hub/circles/:id/members undocumented

/hub/circles/:id/members

DELETE /hub/circles/:id/members: leave.

Handled by api_leave_circle
Parameters
id string · path
required
Responses
200Successful Response
DELETE /hub/circles/example/members
1curl -X DELETE "http://localhost:8000/hub/circles/example/members"
1fetch("http://localhost:8000/hub/circles/example/members", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/hub/circles/example/members")
4print(response.json())
200 Example Response
No Body
DELETE /hub/follows/:target_mrn undocumented

/hub/follows/:target_mrn

DELETE /hub/follows/:target_mrn (the MRN may arrive URL-encoded).

Handled by api_unfollow
Parameters
target_mrn string · path
required
Responses
200Successful Response
DELETE /hub/follows/example
1curl -X DELETE "http://localhost:8000/hub/follows/example"
1fetch("http://localhost:8000/hub/follows/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/hub/follows/example")
4print(response.json())
200 Example Response
No Body
GET /hub/posts undocumented

/hub/posts

GET /hub/posts?feed=everyone|following|circle&circle_id=&author= : newest first.

Handled by api_list_posts
Responses
200Successful Response
GET /hub/posts
1curl "http://localhost:8000/hub/posts"
1fetch("http://localhost:8000/hub/posts")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/hub/posts")
4print(response.json())
200 Example Response
No Body
GET /hub/posts/:id undocumented

/hub/posts/:id

GET /hub/posts/:id

Handled by api_get_post
Parameters
id string · path
required
Responses
200Successful Response
GET /hub/posts/example
1curl "http://localhost:8000/hub/posts/example"
1fetch("http://localhost:8000/hub/posts/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/hub/posts/example")
4print(response.json())
200 Example Response
No Body
GET /hub/posts/:id/replies undocumented

/hub/posts/:id/replies

GET /hub/posts/:id/replies: oldest first.

Handled by api_list_replies
Parameters
id string · path
required
Responses
200Successful Response
GET /hub/posts/example/replies
1curl "http://localhost:8000/hub/posts/example/replies"
1fetch("http://localhost:8000/hub/posts/example/replies")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/hub/posts/example/replies")
4print(response.json())
200 Example Response
No Body
GET /hub/bookmarks undocumented

/hub/bookmarks

GET /hub/bookmarks: what you saved, most recent first.

Handled by api_list_bookmarks
Responses
200Successful Response
GET /hub/bookmarks
1curl "http://localhost:8000/hub/bookmarks"
1fetch("http://localhost:8000/hub/bookmarks")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/hub/bookmarks")
4print(response.json())
200 Example Response
No Body
GET /hub/events undocumented

/hub/events

GET /hub/events: events posted in the Hub that have not happened yet, soonest first.

Handled by api_list_events
Responses
200Successful Response
GET /hub/events
1curl "http://localhost:8000/hub/events"
1fetch("http://localhost:8000/hub/events")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/hub/events")
4print(response.json())
200 Example Response
No Body
GET /hub/circles undocumented

/hub/circles

GET /hub/circles: every circle, the ones you joined first.

Handled by api_list_circles
Responses
200Successful Response
GET /hub/circles
1curl "http://localhost:8000/hub/circles"
1fetch("http://localhost:8000/hub/circles")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/hub/circles")
4print(response.json())
200 Example Response
No Body
GET /hub/follows undocumented

/hub/follows

GET /hub/follows: who you follow.

Handled by api_list_follows
Responses
200Successful Response
GET /hub/follows
1curl "http://localhost:8000/hub/follows"
1fetch("http://localhost:8000/hub/follows")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/hub/follows")
4print(response.json())
200 Example Response
No Body
POST /hub/posts

Post to the Hub

POST /hub/posts: words, media, and optionally a circle, a poll or an event.

Handled by api_create_post
Body · CreateHubPostapplication/json
content string · max length: 5000
media array
circle_id string · min length: 1 · max length: 64
poll object
event object
propertyName anything
Responses
200Successful Response
POST /hub/posts
1curl -X POST "http://localhost:8000/hub/posts" \
2 -H "Content-Type: application/json" \
3 -d '{"content":"string","media":[{"key":"string","filename":"string","type":"string"}],"circle_id":"string","poll":{"options":["string"],"closes_at":"2024-01-01T12:00:00Z"},"event":{"title":"string","starts_at":"2024-01-01T12:00:00Z","ends_at":"2024-01-01T12:00:00Z","location":"string"}}'
1fetch("http://localhost:8000/hub/posts", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "content": "string",
6 "media": [
7 {
8 "key": "string",
9 "filename": "string",
10 "type": "string"
11 }
12 ],
13 "circle_id": "string",
14 "poll": {
15 "options": [
16 "string"
17 ],
18 "closes_at": "2024-01-01T12:00:00Z"
19 },
20 "event": {
21 "title": "string",
22 "starts_at": "2024-01-01T12:00:00Z",
23 "ends_at": "2024-01-01T12:00:00Z",
24 "location": "string"
25 }
26}),
27})
28 .then((res) => res.json())
29 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/hub/posts",
5 json={"content":"string","media":[{"key":"string","filename":"string","type":"string"}],"circle_id":"string","poll":{"options":["string"],"closes_at":"2024-01-01T12:00:00Z"},"event":{"title":"string","starts_at":"2024-01-01T12:00:00Z","ends_at":"2024-01-01T12:00:00Z","location":"string"}},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /hub/posts/:id/replies

Reply to a post

POST /hub/posts/:id/replies

Handled by api_create_reply
Parameters
id string · path
required
Body · CreateHubReplyapplication/json
content string · max length: 5000
media array
propertyName anything
Responses
200Successful Response
POST /hub/posts/example/replies
1curl -X POST "http://localhost:8000/hub/posts/example/replies" \
2 -H "Content-Type: application/json" \
3 -d '{"content":"string","media":[{"key":"string","filename":"string","type":"string"}]}'
1fetch("http://localhost:8000/hub/posts/example/replies", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "content": "string",
6 "media": [
7 {
8 "key": "string",
9 "filename": "string",
10 "type": "string"
11 }
12 ]
13}),
14})
15 .then((res) => res.json())
16 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/hub/posts/example/replies",
5 json={"content":"string","media":[{"key":"string","filename":"string","type":"string"}]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /hub/posts/:id/reactions

React to a post

POST /hub/posts/:id/reactions {reaction_type}: add yours, or change it.

Handled by api_react
Parameters
id string · path
required
Body · HubReactionapplication/json
reaction_type
required
propertyName anything
Responses
200Successful Response
POST /hub/posts/example/reactions
1curl -X POST "http://localhost:8000/hub/posts/example/reactions" \
2 -H "Content-Type: application/json" \
3 -d '{"reaction_type":null}'
1fetch("http://localhost:8000/hub/posts/example/reactions", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "reaction_type": null
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/hub/posts/example/reactions",
5 json={"reaction_type":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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.

Handled by api_repost
Parameters
id string · path
required
Body · CreateHubRepostapplication/json
content string · max length: 5000
propertyName anything
Responses
200Successful Response
POST /hub/posts/example/reposts
1curl -X POST "http://localhost:8000/hub/posts/example/reposts" \
2 -H "Content-Type: application/json" \
3 -d '{"content":"string"}'
1fetch("http://localhost:8000/hub/posts/example/reposts", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "content": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/hub/posts/example/reposts",
5 json={"content":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /hub/posts/:id/votes

Vote in a poll

POST /hub/posts/:id/votes {option_id}: your one vote; voting again moves it.

Handled by api_vote
Parameters
id string · path
required
Body · HubVoteapplication/json
option_id string · min length: 1 · max length: 64
required
propertyName anything
Responses
200Successful Response
POST /hub/posts/example/votes
1curl -X POST "http://localhost:8000/hub/posts/example/votes" \
2 -H "Content-Type: application/json" \
3 -d '{"option_id":"string"}'
1fetch("http://localhost:8000/hub/posts/example/votes", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "option_id": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/hub/posts/example/votes",
5 json={"option_id":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /hub/posts/:id/bookmarks undocumented

/hub/posts/:id/bookmarks

POST /hub/posts/:id/bookmarks

Handled by api_bookmark
Parameters
id string · path
required
Responses
200Successful Response
POST /hub/posts/example/bookmarks
1curl -X POST "http://localhost:8000/hub/posts/example/bookmarks"
1fetch("http://localhost:8000/hub/posts/example/bookmarks", { method: "POST" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.post("http://localhost:8000/hub/posts/example/bookmarks")
4print(response.json())
200 Example Response
No Body
POST /hub/circles

Start a circle

POST /hub/circles {name, description?}: you start it and are its first member.

Handled by api_create_circle
Body · CreateHubCircleapplication/json
name string · min length: 1 · max length: 60
required
description string · max length: 300
propertyName anything
Responses
200Successful Response
POST /hub/circles
1curl -X POST "http://localhost:8000/hub/circles" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","description":"string"}'
1fetch("http://localhost:8000/hub/circles", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "description": "string"
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/hub/circles",
5 json={"name":"string","description":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /hub/circles/:id/members undocumented

/hub/circles/:id/members

POST /hub/circles/:id/members: join.

Handled by api_join_circle
Parameters
id string · path
required
Responses
200Successful Response
POST /hub/circles/example/members
1curl -X POST "http://localhost:8000/hub/circles/example/members"
1fetch("http://localhost:8000/hub/circles/example/members", { method: "POST" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.post("http://localhost:8000/hub/circles/example/members")
4print(response.json())
200 Example Response
No Body
POST /hub/follows

Follow a member

POST /hub/follows {target_mrn}

Handled by api_follow
Body · HubFollowapplication/json
target_mrn string · min length: 1 · max length: 120
required
propertyName anything
Responses
200Successful Response
POST /hub/follows
1curl -X POST "http://localhost:8000/hub/follows" \
2 -H "Content-Type: application/json" \
3 -d '{"target_mrn":"string"}'
1fetch("http://localhost:8000/hub/follows", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "target_mrn": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/hub/follows",
5 json={"target_mrn":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /hub/posts/:id/rsvp

Say if you're going to an event

PUT /hub/posts/:id/rsvp {status}: going, maybe or not going.

Handled by api_set_rsvp
Parameters
id string · path
required
Body · HubRsvpapplication/json
status
required
propertyName anything
Responses
200Successful Response
PUT /hub/posts/example/rsvp
1curl -X PUT "http://localhost:8000/hub/posts/example/rsvp" \
2 -H "Content-Type: application/json" \
3 -d '{"status":null}'
1fetch("http://localhost:8000/hub/posts/example/rsvp", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "status": null
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/hub/posts/example/rsvp",
5 json={"status":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
DELETE /installations/:slug undocumented

/installations/:slug

DELETE /installations/:slug — Uninstall an app (admin/owner only).

Handled by api_uninstall_app
Parameters
slug string · path
required
Responses
200Successful Response
DELETE /installations/example
1curl -X DELETE "http://localhost:8000/installations/example"
1fetch("http://localhost:8000/installations/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/installations/example")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_list_installed_apps
Responses
200Successful Response
GET /installations
1curl "http://localhost:8000/installations"
1fetch("http://localhost:8000/installations")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/installations")
4print(response.json())
200 Example Response
No Body
DELETE /interactions/:interaction_id undocumented

/interactions/:interaction_id

DELETE /interactions/:interaction_id — delete an interaction.

Handled by api_delete_interaction
Parameters
interaction_id string · path
required
Responses
200Successful Response
DELETE /interactions/example
1curl -X DELETE "http://localhost:8000/interactions/example"
1fetch("http://localhost:8000/interactions/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/interactions/example")
4print(response.json())
200 Example Response
No Body
GET /interactions undocumented

/interactions

GET /interactions — all interactions (activity reports).

Handled by api_list_interactions
Responses
200Successful Response
GET /interactions
1curl "http://localhost:8000/interactions"
1fetch("http://localhost:8000/interactions")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/interactions")
4print(response.json())
200 Example Response
No Body
POST /interactions

Log an interaction

POST /interactions — log an interaction.

Handled by api_create_interaction
Body · CreateInteractionapplication/json
contact_id string
company_id string
source_mrn string
type
required
direction
subject string · max length: 200
content string · max length: 10000
occurred_at string
required
duration_minutes integer
rating object
propertyName anything
Responses
200Successful Response
POST /interactions
1curl -X POST "http://localhost:8000/interactions" \
2 -H "Content-Type: application/json" \
3 -d '{"contact_id":"string","company_id":"string","source_mrn":"string","type":null,"direction":null,"subject":"string","content":"string","occurred_at":"string","duration_minutes":1,"rating":{"score":1,"comment":"string"}}'
1fetch("http://localhost:8000/interactions", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "contact_id": "string",
6 "company_id": "string",
7 "source_mrn": "string",
8 "type": null,
9 "direction": null,
10 "subject": "string",
11 "content": "string",
12 "occurred_at": "string",
13 "duration_minutes": 1,
14 "rating": {
15 "score": 1,
16 "comment": "string"
17 }
18}),
19})
20 .then((res) => res.json())
21 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/interactions",
5 json={"contact_id":"string","company_id":"string","source_mrn":"string","type":null,"direction":null,"subject":"string","content":"string","occurred_at":"string","duration_minutes":1,"rating":{"score":1,"comment":"string"}},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /interactions/:interaction_id

Update an interaction

PUT /interactions/:interaction_id — update an interaction.

Handled by api_update_interaction
Parameters
interaction_id string · path
required
Body · UpdateInteractionapplication/json
subject string · max length: 200
content string · max length: 10000
occurred_at string
duration_minutes integer
propertyName anything
Responses
200Successful Response
PUT /interactions/example
1curl -X PUT "http://localhost:8000/interactions/example" \
2 -H "Content-Type: application/json" \
3 -d '{"subject":"string","content":"string","occurred_at":"string","duration_minutes":1}'
1fetch("http://localhost:8000/interactions/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "subject": "string",
6 "content": "string",
7 "occurred_at": "string",
8 "duration_minutes": 1
9}),
10})
11 .then((res) => res.json())
12 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/interactions/example",
5 json={"subject":"string","content":"string","occurred_at":"string","duration_minutes":1},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
GET /invoices/:id undocumented

/invoices/:id

GET /invoices/:id — return full invoice data with line items.

Handled by api_get_invoice
Parameters
id string · path
required
Responses
200Successful Response
GET /invoices/example
1curl "http://localhost:8000/invoices/example"
1fetch("http://localhost:8000/invoices/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/invoices/example")
4print(response.json())
200 Example Response
No Body
PATCH /finance/invoices/:entry_id

Issue/void an invoice

Handled by api_patch_invoice
Parameters
entry_id string · path
required
Body · UpdateInvoiceStatusapplication/json
status
required
propertyName anything
Responses
200Successful Response
PATCH /finance/invoices/example
1curl -X PATCH "http://localhost:8000/finance/invoices/example" \
2 -H "Content-Type: application/json" \
3 -d '{"status":null}'
1fetch("http://localhost:8000/finance/invoices/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "status": null
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/finance/invoices/example",
5 json={"status":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /finance/invoices

Create an invoice

Handled by api_create_invoice
Body · CreateInvoiceapplication/json
date string · min length: 10
required
items array
contact_mrn string
company_mrn string
currency
required
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
Responses
200Successful Response
POST /finance/invoices
1curl -X POST "http://localhost:8000/finance/invoices" \
2 -H "Content-Type: application/json" \
3 -d '{"date":"string","items":[{"description":"string","quantity":1.5,"unit_price":1.5,"discount":1.5,"amount":1.5,"account_code":"string","product_mrn":"string","taxes":[{"name":"string","rate":1.5,"amount":1.5,"reverse_charge":null}]}],"contact_mrn":"string","company_mrn":"string","currency":null,"exchange_rate":1.5,"due_date":"string","memo":"string","tags":["string"],"sources":["string"],"adjustments":[{"label":"string","type":null,"value":1.5,"amount":1.5,"account_code":"string"}],"dimensions":null,"idempotency_key":"string"}'
1fetch("http://localhost:8000/finance/invoices", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "date": "string",
6 "items": [
7 {
8 "description": "string",
9 "quantity": 1.5,
10 "unit_price": 1.5,
11 "discount": 1.5,
12 "amount": 1.5,
13 "account_code": "string",
14 "product_mrn": "string",
15 "taxes": [
16 {
17 "name": "string",
18 "rate": 1.5,
19 "amount": 1.5,
20 "reverse_charge": null
21 }
22 ]
23 }
24 ],
25 "contact_mrn": "string",
26 "company_mrn": "string",
27 "currency": null,
28 "exchange_rate": 1.5,
29 "due_date": "string",
30 "memo": "string",
31 "tags": [
32 "string"
33 ],
34 "sources": [
35 "string"
36 ],
37 "adjustments": [
38 {
39 "label": "string",
40 "type": null,
41 "value": 1.5,
42 "amount": 1.5,
43 "account_code": "string"
44 }
45 ],
46 "dimensions": null,
47 "idempotency_key": "string"
48}),
49})
50 .then((res) => res.json())
51 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/finance/invoices",
5 json={"date":"string","items":[{"description":"string","quantity":1.5,"unit_price":1.5,"discount":1.5,"amount":1.5,"account_code":"string","product_mrn":"string","taxes":[{"name":"string","rate":1.5,"amount":1.5,"reverse_charge":null}]}],"contact_mrn":"string","company_mrn":"string","currency":null,"exchange_rate":1.5,"due_date":"string","memo":"string","tags":["string"],"sources":["string"],"adjustments":[{"label":"string","type":null,"value":1.5,"amount":1.5,"account_code":"string"}],"dimensions":null,"idempotency_key":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /finance/invoices/:entry_id/pdfs

Generate invoice PDF

Handled by api_create_invoice_pdf
Parameters
entry_id string · path
required
Body · GeneratePdfapplication/json
template string · max length: 100
propertyName anything
Responses
200Successful Response
POST /finance/invoices/example/pdfs
1curl -X POST "http://localhost:8000/finance/invoices/example/pdfs" \
2 -H "Content-Type: application/json" \
3 -d '{"template":"string"}'
1fetch("http://localhost:8000/finance/invoices/example/pdfs", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "template": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/finance/invoices/example/pdfs",
5 json={"template":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /finance/invoices/:entry_id/sends

Email an invoice

Handled by api_send_invoice
Parameters
entry_id string · path
required
Body · SendInvoiceapplication/json
to string · min length: 1 · max length: 500
required
cc string · max length: 500
subject string · max length: 300
message string · max length: 5000
attach_pdf
propertyName anything
Responses
200Successful Response
POST /finance/invoices/example/sends
1curl -X POST "http://localhost:8000/finance/invoices/example/sends" \
2 -H "Content-Type: application/json" \
3 -d '{"to":"string","cc":"string","subject":"string","message":"string","attach_pdf":null}'
1fetch("http://localhost:8000/finance/invoices/example/sends", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "to": "string",
6 "cc": "string",
7 "subject": "string",
8 "message": "string",
9 "attach_pdf": null
10}),
11})
12 .then((res) => res.json())
13 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/finance/invoices/example/sends",
5 json={"to":"string","cc":"string","subject":"string","message":"string","attach_pdf":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /finance/invoices/:entry_id/reminders

Send an overdue reminder

Handled by api_send_reminder
Parameters
entry_id string · path
required
Body · SendReminderapplication/json
to string · min length: 1 · max length: 500
required
subject string · max length: 300
message string · max length: 5000
propertyName anything
Responses
200Successful Response
POST /finance/invoices/example/reminders
1curl -X POST "http://localhost:8000/finance/invoices/example/reminders" \
2 -H "Content-Type: application/json" \
3 -d '{"to":"string","subject":"string","message":"string"}'
1fetch("http://localhost:8000/finance/invoices/example/reminders", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "to": "string",
6 "subject": "string",
7 "message": "string"
8}),
9})
10 .then((res) => res.json())
11 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/finance/invoices/example/reminders",
5 json={"to":"string","subject":"string","message":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /invoices/:id/charges undocumented

/invoices/:id/charges

POST /invoices/:id/charges — retry charging the default payment method.

Handled by api_retry_invoice_charge
Parameters
id string · path
required
Responses
200Successful Response
POST /invoices/example/charges
1curl -X POST "http://localhost:8000/invoices/example/charges"
1fetch("http://localhost:8000/invoices/example/charges", { method: "POST" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.post("http://localhost:8000/invoices/example/charges")
4print(response.json())
200 Example Response
No Body
PUT /finance/invoices/:entry_id

Update a draft invoice

Handled by api_update_invoice
Parameters
entry_id string · path
required
Body · UpdateInvoiceapplication/json
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
Responses
200Successful Response
PUT /finance/invoices/example
1curl -X PUT "http://localhost:8000/finance/invoices/example" \
2 -H "Content-Type: application/json" \
3 -d '{"date":"string","items":[{"description":"string","quantity":1.5,"unit_price":1.5,"discount":1.5,"amount":1.5,"account_code":"string","product_mrn":"string","taxes":[{"name":"string","rate":1.5,"amount":1.5,"reverse_charge":null}]}],"contact_mrn":"string","company_mrn":"string","currency":null,"exchange_rate":1.5,"due_date":"string","memo":"string","tags":["string"],"adjustments":[{"label":"string","type":null,"value":1.5,"amount":1.5,"account_code":"string"}],"dimensions":null}'
1fetch("http://localhost:8000/finance/invoices/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "date": "string",
6 "items": [
7 {
8 "description": "string",
9 "quantity": 1.5,
10 "unit_price": 1.5,
11 "discount": 1.5,
12 "amount": 1.5,
13 "account_code": "string",
14 "product_mrn": "string",
15 "taxes": [
16 {
17 "name": "string",
18 "rate": 1.5,
19 "amount": 1.5,
20 "reverse_charge": null
21 }
22 ]
23 }
24 ],
25 "contact_mrn": "string",
26 "company_mrn": "string",
27 "currency": null,
28 "exchange_rate": 1.5,
29 "due_date": "string",
30 "memo": "string",
31 "tags": [
32 "string"
33 ],
34 "adjustments": [
35 {
36 "label": "string",
37 "type": null,
38 "value": 1.5,
39 "amount": 1.5,
40 "account_code": "string"
41 }
42 ],
43 "dimensions": null
44}),
45})
46 .then((res) => res.json())
47 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/finance/invoices/example",
5 json={"date":"string","items":[{"description":"string","quantity":1.5,"unit_price":1.5,"discount":1.5,"amount":1.5,"account_code":"string","product_mrn":"string","taxes":[{"name":"string","rate":1.5,"amount":1.5,"reverse_charge":null}]}],"contact_mrn":"string","company_mrn":"string","currency":null,"exchange_rate":1.5,"due_date":"string","memo":"string","tags":["string"],"adjustments":[{"label":"string","type":null,"value":1.5,"amount":1.5,"account_code":"string"}],"dimensions":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /finance/journal-entries/:entry_id

Post/void a journal

Handled by api_patch_journal_entry
Parameters
entry_id string · path
required
Body · UpdateJournalStatusapplication/json
status
required
propertyName anything
Responses
200Successful Response
PATCH /finance/journal-entries/example
1curl -X PATCH "http://localhost:8000/finance/journal-entries/example" \
2 -H "Content-Type: application/json" \
3 -d '{"status":null}'
1fetch("http://localhost:8000/finance/journal-entries/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "status": null
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/finance/journal-entries/example",
5 json={"status":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /finance/journal-entries

Create a journal entry

Handled by api_create_journal_entry
Body · CreateJournalEntryapplication/json
date string · min length: 10
required
lines array
required
memo string · max length: 5000
currency
required
exchange_rate number
tags array
dimensions
idempotency_key string · max length: 100
propertyName anything
Responses
200Successful Response
POST /finance/journal-entries
1curl -X POST "http://localhost:8000/finance/journal-entries" \
2 -H "Content-Type: application/json" \
3 -d '{"date":"string","lines":[{"account_code":"string","description":"string","debit":1.5,"credit":1.5,"dimensions":null}],"memo":"string","currency":null,"exchange_rate":1.5,"tags":["string"],"dimensions":null,"idempotency_key":"string"}'
1fetch("http://localhost:8000/finance/journal-entries", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "date": "string",
6 "lines": [
7 {
8 "account_code": "string",
9 "description": "string",
10 "debit": 1.5,
11 "credit": 1.5,
12 "dimensions": null
13 }
14 ],
15 "memo": "string",
16 "currency": null,
17 "exchange_rate": 1.5,
18 "tags": [
19 "string"
20 ],
21 "dimensions": null,
22 "idempotency_key": "string"
23}),
24})
25 .then((res) => res.json())
26 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/finance/journal-entries",
5 json={"date":"string","lines":[{"account_code":"string","description":"string","debit":1.5,"credit":1.5,"dimensions":null}],"memo":"string","currency":null,"exchange_rate":1.5,"tags":["string"],"dimensions":null,"idempotency_key":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /finance/journal-entries/:entry_id

Update a draft journal

Handled by api_update_journal_entry
Parameters
entry_id string · path
required
Body · UpdateJournalEntryapplication/json
date string · min length: 10
lines array
memo string · max length: 5000
currency
exchange_rate number
tags array
dimensions
propertyName anything
Responses
200Successful Response
PUT /finance/journal-entries/example
1curl -X PUT "http://localhost:8000/finance/journal-entries/example" \
2 -H "Content-Type: application/json" \
3 -d '{"date":"string","lines":[{"account_code":"string","description":"string","debit":1.5,"credit":1.5,"dimensions":null}],"memo":"string","currency":null,"exchange_rate":1.5,"tags":["string"],"dimensions":null}'
1fetch("http://localhost:8000/finance/journal-entries/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "date": "string",
6 "lines": [
7 {
8 "account_code": "string",
9 "description": "string",
10 "debit": 1.5,
11 "credit": 1.5,
12 "dimensions": null
13 }
14 ],
15 "memo": "string",
16 "currency": null,
17 "exchange_rate": 1.5,
18 "tags": [
19 "string"
20 ],
21 "dimensions": null
22}),
23})
24 .then((res) => res.json())
25 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/finance/journal-entries/example",
5 json={"date":"string","lines":[{"account_code":"string","description":"string","debit":1.5,"credit":1.5,"dimensions":null}],"memo":"string","currency":null,"exchange_rate":1.5,"tags":["string"],"dimensions":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /leave-balances/:id/adjustments

Adjust a leave balance

Manual balance adjustment (admin only).

Handled by api_adjust_balance
Parameters
id string · path
required
Body · AdjustBalanceapplication/json
amount number
required
reason string · min length: 1 · max length: 500
required
propertyName anything
Responses
200Successful Response
POST /leave-balances/example/adjustments
1curl -X POST "http://localhost:8000/leave-balances/example/adjustments" \
2 -H "Content-Type: application/json" \
3 -d '{"amount":1.5,"reason":"string"}'
1fetch("http://localhost:8000/leave-balances/example/adjustments", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "amount": 1.5,
6 "reason": "string"
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/leave-balances/example/adjustments",
5 json={"amount":1.5,"reason":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
DELETE /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.

Handled by api_remove_policy_members
Parameters
id string · path
required
Body · PolicyMemberSelectionapplication/json
worker_mrns array
match object
exclude_worker_mrns array
propertyName anything
Responses
200Successful Response
DELETE /leave-policies/example/members
1curl -X DELETE "http://localhost:8000/leave-policies/example/members" \
2 -H "Content-Type: application/json" \
3 -d '{"worker_mrns":["string"],"match":{"q":"string","department_id":["string"],"location_mrn":["string"],"manager_id":["string"],"employment_type":["string"]},"exclude_worker_mrns":["string"]}'
1fetch("http://localhost:8000/leave-policies/example/members", {
2 method: "DELETE",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "worker_mrns": [
6 "string"
7 ],
8 "match": {
9 "q": "string",
10 "department_id": [
11 "string"
12 ],
13 "location_mrn": [
14 "string"
15 ],
16 "manager_id": [
17 "string"
18 ],
19 "employment_type": [
20 "string"
21 ]
22 },
23 "exclude_worker_mrns": [
24 "string"
25 ]
26}),
27})
28 .then((res) => res.json())
29 .then(console.log);
1import requests
2
3response = requests.delete(
4 "http://localhost:8000/leave-policies/example/members",
5 json={"worker_mrns":["string"],"match":{"q":"string","department_id":["string"],"location_mrn":["string"],"manager_id":["string"],"employment_type":["string"]},"exclude_worker_mrns":["string"]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /leave-policies

Create a leave policy

Handled by api_create_policy
Body · CreatePolicyapplication/json
name string · min length: 1 · max length: 100
required
type
required
allowance number
required
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
Responses
200Successful Response
POST /leave-policies
1curl -X POST "http://localhost:8000/leave-policies" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","type":null,"allowance":1.5,"description":"string","accrual":null,"max_carry_over":1.5,"requires_approval":null,"min_notice_days":1,"max_consecutive_days":1,"applies_to":null,"cycle_start":null,"default_approver_mrns":["string"]}'
1fetch("http://localhost:8000/leave-policies", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "type": null,
7 "allowance": 1.5,
8 "description": "string",
9 "accrual": null,
10 "max_carry_over": 1.5,
11 "requires_approval": null,
12 "min_notice_days": 1,
13 "max_consecutive_days": 1,
14 "applies_to": null,
15 "cycle_start": null,
16 "default_approver_mrns": [
17 "string"
18 ]
19}),
20})
21 .then((res) => res.json())
22 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/leave-policies",
5 json={"name":"string","type":null,"allowance":1.5,"description":"string","accrual":null,"max_carry_over":1.5,"requires_approval":null,"min_notice_days":1,"max_consecutive_days":1,"applies_to":null,"cycle_start":null,"default_approver_mrns":["string"]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /leave-policies/:id/members

Assign workers to a leave policy

POST /leave-policies/:id/members — Assign workers to a policy and provision balances.

Handled by api_add_policy_members
Parameters
id string · path
required
Body · PolicyMemberSelectionapplication/json
worker_mrns array
match object
exclude_worker_mrns array
propertyName anything
Responses
200Successful Response
POST /leave-policies/example/members
1curl -X POST "http://localhost:8000/leave-policies/example/members" \
2 -H "Content-Type: application/json" \
3 -d '{"worker_mrns":["string"],"match":{"q":"string","department_id":["string"],"location_mrn":["string"],"manager_id":["string"],"employment_type":["string"]},"exclude_worker_mrns":["string"]}'
1fetch("http://localhost:8000/leave-policies/example/members", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "worker_mrns": [
6 "string"
7 ],
8 "match": {
9 "q": "string",
10 "department_id": [
11 "string"
12 ],
13 "location_mrn": [
14 "string"
15 ],
16 "manager_id": [
17 "string"
18 ],
19 "employment_type": [
20 "string"
21 ]
22 },
23 "exclude_worker_mrns": [
24 "string"
25 ]
26}),
27})
28 .then((res) => res.json())
29 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/leave-policies/example/members",
5 json={"worker_mrns":["string"],"match":{"q":"string","department_id":["string"],"location_mrn":["string"],"manager_id":["string"],"employment_type":["string"]},"exclude_worker_mrns":["string"]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /leave-policies/:id

Update a leave policy

Handled by api_update_policy
Parameters
id string · path
required
Body · UpdatePolicyapplication/json
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
Responses
200Successful Response
PUT /leave-policies/example
1curl -X PUT "http://localhost:8000/leave-policies/example" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","description":"string","allowance":1.5,"accrual":null,"max_carry_over":1.5,"requires_approval":null,"min_notice_days":1,"max_consecutive_days":1,"applies_to":null,"cycle_start":null,"is_active":null,"default_approver_mrns":["string"]}'
1fetch("http://localhost:8000/leave-policies/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "description": "string",
7 "allowance": 1.5,
8 "accrual": null,
9 "max_carry_over": 1.5,
10 "requires_approval": null,
11 "min_notice_days": 1,
12 "max_consecutive_days": 1,
13 "applies_to": null,
14 "cycle_start": null,
15 "is_active": null,
16 "default_approver_mrns": [
17 "string"
18 ]
19}),
20})
21 .then((res) => res.json())
22 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/leave-policies/example",
5 json={"name":"string","description":"string","allowance":1.5,"accrual":null,"max_carry_over":1.5,"requires_approval":null,"min_notice_days":1,"max_consecutive_days":1,"applies_to":null,"cycle_start":null,"is_active":null,"default_approver_mrns":["string"]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
GET /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.

Handled by api_list_balances
Responses
200Successful Response
GET /leave-balances
1curl "http://localhost:8000/leave-balances"
1fetch("http://localhost:8000/leave-balances")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/leave-balances")
4print(response.json())
200 Example Response
No Body
GET /leave-balances/:worker_mrn undocumented

/leave-balances/:worker_mrn

List balances for a specific worker (manager/admin).

Handled by api_get_worker_balances
Parameters
worker_mrn string · path
required
Responses
200Successful Response
GET /leave-balances/example
1curl "http://localhost:8000/leave-balances/example"
1fetch("http://localhost:8000/leave-balances/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/leave-balances/example")
4print(response.json())
200 Example Response
No Body
GET /leave-calculate-days undocumented

/leave-calculate-days

Calculate working days between two dates.

Handled by api_calculate_days
Responses
200Successful Response
GET /leave-calculate-days
1curl "http://localhost:8000/leave-calculate-days"
1fetch("http://localhost:8000/leave-calculate-days")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/leave-calculate-days")
4print(response.json())
200 Example Response
No Body
GET /leave-calendar undocumented

/leave-calendar

Team calendar — approved PTOs + holidays for a date range.

Handled by api_calendar
Responses
200Successful Response
GET /leave-calendar
1curl "http://localhost:8000/leave-calendar"
1fetch("http://localhost:8000/leave-calendar")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/leave-calendar")
4print(response.json())
200 Example Response
No Body
DELETE /leave-policies/:id undocumented

/leave-policies/:id

Handled by api_delete_policy
Parameters
id string · path
required
Responses
200Successful Response
DELETE /leave-policies/example
1curl -X DELETE "http://localhost:8000/leave-policies/example"
1fetch("http://localhost:8000/leave-policies/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/leave-policies/example")
4print(response.json())
200 Example Response
No Body
DELETE /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.

Handled by api_remove_policy_member
Parameters
id string · path
required
worker_mrn string · path
required
Responses
200Successful Response
DELETE /leave-policies/example/members/example
1curl -X DELETE "http://localhost:8000/leave-policies/example/members/example"
1fetch("http://localhost:8000/leave-policies/example/members/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/leave-policies/example/members/example")
4print(response.json())
200 Example Response
No Body
GET /leave-policies undocumented

/leave-policies

Handled by api_list_policies
Responses
200Successful Response
GET /leave-policies
1curl "http://localhost:8000/leave-policies"
1fetch("http://localhost:8000/leave-policies")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/leave-policies")
4print(response.json())
200 Example Response
No Body
GET /leave-policies/:id undocumented

/leave-policies/:id

Handled by api_get_policy
Parameters
id string · path
required
Responses
200Successful Response
GET /leave-policies/example
1curl "http://localhost:8000/leave-policies/example"
1fetch("http://localhost:8000/leave-policies/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/leave-policies/example")
4print(response.json())
200 Example Response
No Body
GET /leave-policies/:id/members undocumented

/leave-policies/:id/members

GET /leave-policies/:id/members — List workers assigned to a policy.

Handled by api_list_policy_members
Parameters
id string · path
required
Responses
200Successful Response
GET /leave-policies/example/members
1curl "http://localhost:8000/leave-policies/example/members"
1fetch("http://localhost:8000/leave-policies/example/members")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/leave-policies/example/members")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_list_policy_candidates
Parameters
id string · path
required
Responses
200Successful Response
GET /leave-policies/example/candidates
1curl "http://localhost:8000/leave-policies/example/candidates"
1fetch("http://localhost:8000/leave-policies/example/candidates")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/leave-policies/example/candidates")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_list_worker_filters
Parameters
id string · path
required
Responses
200Successful Response
GET /leave-policies/example/worker-filters
1curl "http://localhost:8000/leave-policies/example/worker-filters"
1fetch("http://localhost:8000/leave-policies/example/worker-filters")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/leave-policies/example/worker-filters")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_list_worker_filter_options
Parameters
id string · path
required
key string · path
required
Responses
200Successful Response
GET /leave-policies/example/worker-filters/example/options
1curl "http://localhost:8000/leave-policies/example/worker-filters/example/options"
1fetch("http://localhost:8000/leave-policies/example/worker-filters/example/options")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/leave-policies/example/worker-filters/example/options")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_reconciliation_preview
Responses
200Successful Response
GET /leave-reconciliation
1curl "http://localhost:8000/leave-reconciliation"
1fetch("http://localhost:8000/leave-reconciliation")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/leave-reconciliation")
4print(response.json())
200 Example Response
No Body
POST /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.

Handled by api_apply_reconciliation
Responses
200Successful Response
POST /leave-reconciliation
1curl -X POST "http://localhost:8000/leave-reconciliation"
1fetch("http://localhost:8000/leave-reconciliation", { method: "POST" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.post("http://localhost:8000/leave-reconciliation")
4print(response.json())
200 Example Response
No Body
PATCH /calls/:id/links/:link_id

Update a join link

Handled by api_update_link
Parameters
id string · path
required
link_id string · path
required
Body · UpdateLinkapplication/json
is_active
external_join_mode
propertyName anything
Responses
200Successful Response
PATCH /calls/example/links/example
1curl -X PATCH "http://localhost:8000/calls/example/links/example" \
2 -H "Content-Type: application/json" \
3 -d '{"is_active":null,"external_join_mode":null}'
1fetch("http://localhost:8000/calls/example/links/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "is_active": null,
6 "external_join_mode": null
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/calls/example/links/example",
5 json={"is_active":null,"external_join_mode":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /calls/:id/links

Create a join link

Handled by api_create_link
Parameters
id string · path
required
Body · CreateLinkapplication/json
expires_at string
guest_name string · max length: 200
guest_email string · max length: 200
external_join_mode
propertyName anything
Responses
200Successful Response
POST /calls/example/links
1curl -X POST "http://localhost:8000/calls/example/links" \
2 -H "Content-Type: application/json" \
3 -d '{"expires_at":"string","guest_name":"string","guest_email":"string","external_join_mode":null}'
1fetch("http://localhost:8000/calls/example/links", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "expires_at": "string",
6 "guest_name": "string",
7 "guest_email": "string",
8 "external_join_mode": null
9}),
10})
11 .then((res) => res.json())
12 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/calls/example/links",
5 json={"expires_at":"string","guest_name":"string","guest_email":"string","external_join_mode":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /chats/lists/:list_id

Update a chat list

PATCH /chats/lists/:list_id — rename or reorder a list.

Handled by api_update_chat_list
Parameters
list_id string · path
required
Body · UpdateChatListapplication/json
name string · min length: 1 · max length: 50
position integer
propertyName anything
Responses
200Successful Response
PATCH /chats/lists/example
1curl -X PATCH "http://localhost:8000/chats/lists/example" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","position":1}'
1fetch("http://localhost:8000/chats/lists/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "position": 1
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/chats/lists/example",
5 json={"name":"string","position":1},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /chats/lists

Create a chat list

POST /chats/lists — create a personal chat list.

Handled by api_create_chat_list
Body · CreateChatListapplication/json
name string · min length: 1 · max length: 50
required
chat_ids array
propertyName anything
Responses
200Successful Response
POST /chats/lists
1curl -X POST "http://localhost:8000/chats/lists" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","chat_ids":["string"]}'
1fetch("http://localhost:8000/chats/lists", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "chat_ids": [
7 "string"
8 ]
9}),
10})
11 .then((res) => res.json())
12 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/chats/lists",
5 json={"name":"string","chat_ids":["string"]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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).

Handled by api_create_macro_preview
Body · MacroPreviewapplication/json
macro string · min length: 2 · max length: 40
required
args
payload
event_name string · max length: 200
propertyName anything
Responses
200Successful Response
POST /wands/macro-previews
1curl -X POST "http://localhost:8000/wands/macro-previews" \
2 -H "Content-Type: application/json" \
3 -d '{"macro":"string","args":null,"payload":null,"event_name":"string"}'
1fetch("http://localhost:8000/wands/macro-previews", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "macro": "string",
6 "args": null,
7 "payload": null,
8 "event_name": "string"
9}),
10})
11 .then((res) => res.json())
12 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/wands/macro-previews",
5 json={"macro":"string","args":null,"payload":null,"event_name":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
DELETE /mail/accounts/:account_id undocumented

/mail/accounts/:account_id

Handled by api_delete_account
Parameters
account_id string · path
required
Responses
200Successful Response
DELETE /mail/accounts/example
1curl -X DELETE "http://localhost:8000/mail/accounts/example"
1fetch("http://localhost:8000/mail/accounts/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/mail/accounts/example")
4print(response.json())
200 Example Response
No Body
DELETE /mail/accounts/:account_id/messages/:message_id undocumented

/mail/accounts/:account_id/messages/:message_id

Handled by api_delete_message
Parameters
account_id string · path
required
message_id string · path
required
Responses
200Successful Response
DELETE /mail/accounts/example/messages/example
1curl -X DELETE "http://localhost:8000/mail/accounts/example/messages/example"
1fetch("http://localhost:8000/mail/accounts/example/messages/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/mail/accounts/example/messages/example")
4print(response.json())
200 Example Response
No Body
DELETE /mail/accounts/:account_id/signatures/:signature_id undocumented

/mail/accounts/:account_id/signatures/:signature_id

Handled by api_delete_signature
Parameters
account_id string · path
required
signature_id string · path
required
Responses
200Successful Response
DELETE /mail/accounts/example/signatures/example
1curl -X DELETE "http://localhost:8000/mail/accounts/example/signatures/example"
1fetch("http://localhost:8000/mail/accounts/example/signatures/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/mail/accounts/example/signatures/example")
4print(response.json())
200 Example Response
No Body
DELETE /mail/accounts/:account_id/filters/:filter_id undocumented

/mail/accounts/:account_id/filters/:filter_id

Handled by api_delete_filter
Parameters
account_id string · path
required
filter_id string · path
required
Responses
200Successful Response
DELETE /mail/accounts/example/filters/example
1curl -X DELETE "http://localhost:8000/mail/accounts/example/filters/example"
1fetch("http://localhost:8000/mail/accounts/example/filters/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/mail/accounts/example/filters/example")
4print(response.json())
200 Example Response
No Body
DELETE /mail/accounts/:account_id/blocked-senders/:blocked_id undocumented

/mail/accounts/:account_id/blocked-senders/:blocked_id

Handled by api_delete_blocked_sender
Parameters
account_id string · path
required
blocked_id string · path
required
Responses
200Successful Response
DELETE /mail/accounts/example/blocked-senders/example
1curl -X DELETE "http://localhost:8000/mail/accounts/example/blocked-senders/example"
1fetch("http://localhost:8000/mail/accounts/example/blocked-senders/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/mail/accounts/example/blocked-senders/example")
4print(response.json())
200 Example Response
No Body
DELETE /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.

Handled by api_delete_domain
Parameters
domain_id string · path
required
Responses
200Successful Response
DELETE /mail/domains/example
1curl -X DELETE "http://localhost:8000/mail/domains/example"
1fetch("http://localhost:8000/mail/domains/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/mail/domains/example")
4print(response.json())
200 Example Response
No Body
DELETE /mail/mailboxes/:mailbox_id undocumented

/mail/mailboxes/:mailbox_id

Handled by api_delete_mailbox
Parameters
mailbox_id string · path
required
Responses
200Successful Response
DELETE /mail/mailboxes/example
1curl -X DELETE "http://localhost:8000/mail/mailboxes/example"
1fetch("http://localhost:8000/mail/mailboxes/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/mail/mailboxes/example")
4print(response.json())
200 Example Response
No Body
DELETE /mail/groups/:group_id undocumented

/mail/groups/:group_id

Remove a shared mailbox, its aliases and its backing mailbox.

Handled by api_delete_group
Parameters
group_id string · path
required
Responses
200Successful Response
DELETE /mail/groups/example
1curl -X DELETE "http://localhost:8000/mail/groups/example"
1fetch("http://localhost:8000/mail/groups/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/mail/groups/example")
4print(response.json())
200 Example Response
No Body
DELETE /mail/groups/:group_id/members/:member_id undocumented

/mail/groups/:group_id/members/:member_id

Handled by api_remove_group_member
Parameters
group_id string · path
required
member_id string · path
required
Responses
200Successful Response
DELETE /mail/groups/example/members/example
1curl -X DELETE "http://localhost:8000/mail/groups/example/members/example"
1fetch("http://localhost:8000/mail/groups/example/members/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/mail/groups/example/members/example")
4print(response.json())
200 Example Response
No Body
DELETE /mail/groups/:group_id/messages/:message_id undocumented

/mail/groups/:group_id/messages/:message_id

Handled by api_delete_group_message
Parameters
group_id string · path
required
message_id string · path
required
Responses
200Successful Response
DELETE /mail/groups/example/messages/example
1curl -X DELETE "http://localhost:8000/mail/groups/example/messages/example"
1fetch("http://localhost:8000/mail/groups/example/messages/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/mail/groups/example/messages/example")
4print(response.json())
200 Example Response
No Body
DELETE /mail/drafts/:draft_id undocumented

/mail/drafts/:draft_id

Handled by api_delete_draft
Parameters
draft_id string · path
required
Responses
200Successful Response
DELETE /mail/drafts/example
1curl -X DELETE "http://localhost:8000/mail/drafts/example"
1fetch("http://localhost:8000/mail/drafts/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/mail/drafts/example")
4print(response.json())
200 Example Response
No Body
DELETE /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.

Handled by api_delete_outbox_key
Parameters
mailbox_id string · path
required
key_id string · path
required
Responses
200Successful Response
DELETE /mail/mailboxes/example/outbox-keys/example
1curl -X DELETE "http://localhost:8000/mail/mailboxes/example/outbox-keys/example"
1fetch("http://localhost:8000/mail/mailboxes/example/outbox-keys/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/mail/mailboxes/example/outbox-keys/example")
4print(response.json())
200 Example Response
No Body
GET /mail/oauth/:provider/authorize undocumented

/mail/oauth/:provider/authorize

Handled by authorize
Parameters
provider string · path
required
Responses
200Successful Response
GET /mail/oauth/example/authorize
1curl "http://localhost:8000/mail/oauth/example/authorize"
1fetch("http://localhost:8000/mail/oauth/example/authorize")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/mail/oauth/example/authorize")
4print(response.json())
200 Example Response
No Body
GET /mail/oauth/:provider/callback undocumented

/mail/oauth/:provider/callback

Handled by callback
Parameters
provider string · path
required
Responses
200Successful Response
GET /mail/oauth/example/callback
1curl "http://localhost:8000/mail/oauth/example/callback"
1fetch("http://localhost:8000/mail/oauth/example/callback")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/mail/oauth/example/callback")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_list_accounts
Responses
200Successful Response
GET /mail/accounts
1curl "http://localhost:8000/mail/accounts"
1fetch("http://localhost:8000/mail/accounts")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/mail/accounts")
4print(response.json())
200 Example Response
No Body
GET /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).

Handled by api_recipient_suggestions
Responses
200Successful Response
GET /mail/recipients
1curl "http://localhost:8000/mail/recipients"
1fetch("http://localhost:8000/mail/recipients")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/mail/recipients")
4print(response.json())
200 Example Response
No Body
GET /mail/unified/messages undocumented

/mail/unified/messages

One folder across the member's unified accounts and shared inboxes, newest first, paged.

Handled by api_unified_inbox
Responses
200Successful Response
GET /mail/unified/messages
1curl "http://localhost:8000/mail/unified/messages"
1fetch("http://localhost:8000/mail/unified/messages")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/mail/unified/messages")
4print(response.json())
200 Example Response
No Body
GET /mail/accounts/:account_id/messages undocumented

/mail/accounts/:account_id/messages

Handled by api_list_messages
Parameters
account_id string · path
required
Responses
200Successful Response
GET /mail/accounts/example/messages
1curl "http://localhost:8000/mail/accounts/example/messages"
1fetch("http://localhost:8000/mail/accounts/example/messages")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/mail/accounts/example/messages")
4print(response.json())
200 Example Response
No Body
GET /mail/accounts/:account_id/messages/:message_id undocumented

/mail/accounts/:account_id/messages/:message_id

Handled by api_get_message
Parameters
account_id string · path
required
message_id string · path
required
Responses
200Successful Response
GET /mail/accounts/example/messages/example
1curl "http://localhost:8000/mail/accounts/example/messages/example"
1fetch("http://localhost:8000/mail/accounts/example/messages/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/mail/accounts/example/messages/example")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_get_message_attachment
Parameters
account_id string · path
required
message_id string · path
required
index string · path
required
Responses
200Successful Response
GET /mail/accounts/example/messages/example/attachments/example
1curl "http://localhost:8000/mail/accounts/example/messages/example/attachments/example"
1fetch("http://localhost:8000/mail/accounts/example/messages/example/attachments/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/mail/accounts/example/messages/example/attachments/example")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_message_calendar
Parameters
account_id string · path
required
message_id string · path
required
Responses
200Successful Response
GET /mail/accounts/example/messages/example/calendar
1curl "http://localhost:8000/mail/accounts/example/messages/example/calendar"
1fetch("http://localhost:8000/mail/accounts/example/messages/example/calendar")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/mail/accounts/example/messages/example/calendar")
4print(response.json())
200 Example Response
No Body
GET /mail/accounts/:account_id/folders undocumented

/mail/accounts/:account_id/folders

Handled by api_list_folders
Parameters
account_id string · path
required
Responses
200Successful Response
GET /mail/accounts/example/folders
1curl "http://localhost:8000/mail/accounts/example/folders"
1fetch("http://localhost:8000/mail/accounts/example/folders")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/mail/accounts/example/folders")
4print(response.json())
200 Example Response
No Body
GET /mail/accounts/:account_id/signatures undocumented

/mail/accounts/:account_id/signatures

Handled by api_list_signatures
Parameters
account_id string · path
required
Responses
200Successful Response
GET /mail/accounts/example/signatures
1curl "http://localhost:8000/mail/accounts/example/signatures"
1fetch("http://localhost:8000/mail/accounts/example/signatures")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/mail/accounts/example/signatures")
4print(response.json())
200 Example Response
No Body
GET /mail/accounts/:account_id/filters undocumented

/mail/accounts/:account_id/filters

Handled by api_list_filters
Parameters
account_id string · path
required
Responses
200Successful Response
GET /mail/accounts/example/filters
1curl "http://localhost:8000/mail/accounts/example/filters"
1fetch("http://localhost:8000/mail/accounts/example/filters")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/mail/accounts/example/filters")
4print(response.json())
200 Example Response
No Body
GET /mail/accounts/:account_id/blocked-senders undocumented

/mail/accounts/:account_id/blocked-senders

Handled by api_list_blocked_senders
Parameters
account_id string · path
required
Responses
200Successful Response
GET /mail/accounts/example/blocked-senders
1curl "http://localhost:8000/mail/accounts/example/blocked-senders"
1fetch("http://localhost:8000/mail/accounts/example/blocked-senders")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/mail/accounts/example/blocked-senders")
4print(response.json())
200 Example Response
No Body
GET /mail/domains undocumented

/mail/domains

Handled by api_list_domains
Responses
200Successful Response
GET /mail/domains
1curl "http://localhost:8000/mail/domains"
1fetch("http://localhost:8000/mail/domains")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/mail/domains")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_get_domain_dmarc
Parameters
domain_id string · path
required
Responses
200Successful Response
GET /mail/domains/example/dmarc
1curl "http://localhost:8000/mail/domains/example/dmarc"
1fetch("http://localhost:8000/mail/domains/example/dmarc")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/mail/domains/example/dmarc")
4print(response.json())
200 Example Response
No Body
GET /mail/mailboxes undocumented

/mail/mailboxes

Handled by api_list_mailboxes
Responses
200Successful Response
GET /mail/mailboxes
1curl "http://localhost:8000/mail/mailboxes"
1fetch("http://localhost:8000/mail/mailboxes")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/mail/mailboxes")
4print(response.json())
200 Example Response
No Body
GET /mail/imports undocumented

/mail/imports

Handled by api_list_imports
Responses
200Successful Response
GET /mail/imports
1curl "http://localhost:8000/mail/imports"
1fetch("http://localhost:8000/mail/imports")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/mail/imports")
4print(response.json())
200 Example Response
No Body
GET /mail/imports/:import_id undocumented

/mail/imports/:import_id

Handled by api_get_import
Parameters
import_id string · path
required
Responses
200Successful Response
GET /mail/imports/example
1curl "http://localhost:8000/mail/imports/example"
1fetch("http://localhost:8000/mail/imports/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/mail/imports/example")
4print(response.json())
200 Example Response
No Body
GET /mail/groups undocumented

/mail/groups

Handled by api_list_groups
Responses
200Successful Response
GET /mail/groups
1curl "http://localhost:8000/mail/groups"
1fetch("http://localhost:8000/mail/groups")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/mail/groups")
4print(response.json())
200 Example Response
No Body
GET /mail/groups/:group_id/members undocumented

/mail/groups/:group_id/members

Handled by api_list_group_members
Parameters
group_id string · path
required
Responses
200Successful Response
GET /mail/groups/example/members
1curl "http://localhost:8000/mail/groups/example/members"
1fetch("http://localhost:8000/mail/groups/example/members")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/mail/groups/example/members")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_list_group_drafts
Parameters
group_id string · path
required
Responses
200Successful Response
GET /mail/groups/example/drafts
1curl "http://localhost:8000/mail/groups/example/drafts"
1fetch("http://localhost:8000/mail/groups/example/drafts")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/mail/groups/example/drafts")
4print(response.json())
200 Example Response
No Body
GET /mail/groups/:group_id/thread undocumented

/mail/groups/:group_id/thread

The group conversation — sent drafts in order, each showing who sent it.

Handled by api_group_thread
Parameters
group_id string · path
required
Responses
200Successful Response
GET /mail/groups/example/thread
1curl "http://localhost:8000/mail/groups/example/thread"
1fetch("http://localhost:8000/mail/groups/example/thread")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/mail/groups/example/thread")
4print(response.json())
200 Example Response
No Body
GET /mail/groups/:group_id/messages undocumented

/mail/groups/:group_id/messages

Handled by api_list_group_messages
Parameters
group_id string · path
required
Responses
200Successful Response
GET /mail/groups/example/messages
1curl "http://localhost:8000/mail/groups/example/messages"
1fetch("http://localhost:8000/mail/groups/example/messages")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/mail/groups/example/messages")
4print(response.json())
200 Example Response
No Body
GET /mail/groups/:group_id/messages/:message_id undocumented

/mail/groups/:group_id/messages/:message_id

Handled by api_get_group_message
Parameters
group_id string · path
required
message_id string · path
required
Responses
200Successful Response
GET /mail/groups/example/messages/example
1curl "http://localhost:8000/mail/groups/example/messages/example"
1fetch("http://localhost:8000/mail/groups/example/messages/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/mail/groups/example/messages/example")
4print(response.json())
200 Example Response
No Body
GET /mail/groups/:group_id/messages/:message_id/attachments/:index undocumented

/mail/groups/:group_id/messages/:message_id/attachments/:index

Handled by api_get_group_message_attachment
Parameters
group_id string · path
required
message_id string · path
required
index string · path
required
Responses
200Successful Response
GET /mail/groups/example/messages/example/attachments/example
1curl "http://localhost:8000/mail/groups/example/messages/example/attachments/example"
1fetch("http://localhost:8000/mail/groups/example/messages/example/attachments/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/mail/groups/example/messages/example/attachments/example")
4print(response.json())
200 Example Response
No Body
GET /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).

Handled by api_group_message_calendar
Parameters
group_id string · path
required
message_id string · path
required
Responses
200Successful Response
GET /mail/groups/example/messages/example/calendar
1curl "http://localhost:8000/mail/groups/example/messages/example/calendar"
1fetch("http://localhost:8000/mail/groups/example/messages/example/calendar")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/mail/groups/example/messages/example/calendar")
4print(response.json())
200 Example Response
No Body
GET /mail/drafts undocumented

/mail/drafts

The member's own personal (non-group) unsent drafts, newest first.

Handled by api_list_drafts
Responses
200Successful Response
GET /mail/drafts
1curl "http://localhost:8000/mail/drafts"
1fetch("http://localhost:8000/mail/drafts")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/mail/drafts")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_list_outbox_keys
Parameters
mailbox_id string · path
required
Responses
200Successful Response
GET /mail/mailboxes/example/outbox-keys
1curl "http://localhost:8000/mail/mailboxes/example/outbox-keys"
1fetch("http://localhost:8000/mail/mailboxes/example/outbox-keys")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/mail/mailboxes/example/outbox-keys")
4print(response.json())
200 Example Response
No Body
PATCH /mail/accounts/:account_id

Update mail account

Handled by api_update_account
Parameters
account_id string · path
required
Body · UpdateAccountapplication/json
display_name string · max length: 200
show_in_unified
propertyName anything
Responses
200Successful Response
PATCH /mail/accounts/example
1curl -X PATCH "http://localhost:8000/mail/accounts/example" \
2 -H "Content-Type: application/json" \
3 -d '{"display_name":"string","show_in_unified":null}'
1fetch("http://localhost:8000/mail/accounts/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "display_name": "string",
6 "show_in_unified": null
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/mail/accounts/example",
5 json={"display_name":"string","show_in_unified":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /mail/accounts/:account_id/messages/:message_id

Modify a message

Handled by api_modify_message
Parameters
account_id string · path
required
message_id string · path
required
Body · UpdateMessageapplication/json
is_read
is_starred
folder string · min length: 1 · max length: 100
propertyName anything
Responses
200Successful Response
PATCH /mail/accounts/example/messages/example
1curl -X PATCH "http://localhost:8000/mail/accounts/example/messages/example" \
2 -H "Content-Type: application/json" \
3 -d '{"is_read":null,"is_starred":null,"folder":"string"}'
1fetch("http://localhost:8000/mail/accounts/example/messages/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "is_read": null,
6 "is_starred": null,
7 "folder": "string"
8}),
9})
10 .then((res) => res.json())
11 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/mail/accounts/example/messages/example",
5 json={"is_read":null,"is_starred":null,"folder":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /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.

Handled by api_update_group
Parameters
group_id string · path
required
Responses
200Successful Response
PATCH /mail/groups/example
1curl -X PATCH "http://localhost:8000/mail/groups/example"
1fetch("http://localhost:8000/mail/groups/example", { method: "PATCH" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.patch("http://localhost:8000/mail/groups/example")
4print(response.json())
200 Example Response
No Body
PATCH /mail/groups/:group_id/messages/:message_id

Modify a shared-inbox message

Handled by api_modify_group_message
Parameters
group_id string · path
required
message_id string · path
required
Body · UpdateMessageapplication/json
is_read
is_starred
folder string · min length: 1 · max length: 100
propertyName anything
Responses
200Successful Response
PATCH /mail/groups/example/messages/example
1curl -X PATCH "http://localhost:8000/mail/groups/example/messages/example" \
2 -H "Content-Type: application/json" \
3 -d '{"is_read":null,"is_starred":null,"folder":"string"}'
1fetch("http://localhost:8000/mail/groups/example/messages/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "is_read": null,
6 "is_starred": null,
7 "folder": "string"
8}),
9})
10 .then((res) => res.json())
11 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/mail/groups/example/messages/example",
5 json={"is_read":null,"is_starred":null,"folder":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /mail/accounts/:account_id/messages

Send a message

Handled by api_send_message
Parameters
account_id string · path
required
Body · SendMessageapplication/json
to array
required
cc array
bcc array
subject string · max length: 998
required
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
Responses
200Successful Response
POST /mail/accounts/example/messages
1curl -X POST "http://localhost:8000/mail/accounts/example/messages" \
2 -H "Content-Type: application/json" \
3 -d '{"to":[{"email":"user@example.com","name":"string"}],"cc":[{"email":"user@example.com","name":"string"}],"bcc":[{"email":"user@example.com","name":"string"}],"subject":"string","body_text":"string","body_html":"string","is_draft":null,"signature_id":"string","attachments":[{"storage_key":"string","filename":"string","content_type":"string","size":1}],"in_reply_to":"string","references":"string"}'
1fetch("http://localhost:8000/mail/accounts/example/messages", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "to": [
6 {
7 "email": "user@example.com",
8 "name": "string"
9 }
10 ],
11 "cc": [
12 {
13 "email": "user@example.com",
14 "name": "string"
15 }
16 ],
17 "bcc": [
18 {
19 "email": "user@example.com",
20 "name": "string"
21 }
22 ],
23 "subject": "string",
24 "body_text": "string",
25 "body_html": "string",
26 "is_draft": null,
27 "signature_id": "string",
28 "attachments": [
29 {
30 "storage_key": "string",
31 "filename": "string",
32 "content_type": "string",
33 "size": 1
34 }
35 ],
36 "in_reply_to": "string",
37 "references": "string"
38}),
39})
40 .then((res) => res.json())
41 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/mail/accounts/example/messages",
5 json={"to":[{"email":"user@example.com","name":"string"}],"cc":[{"email":"user@example.com","name":"string"}],"bcc":[{"email":"user@example.com","name":"string"}],"subject":"string","body_text":"string","body_html":"string","is_draft":null,"signature_id":"string","attachments":[{"storage_key":"string","filename":"string","content_type":"string","size":1}],"in_reply_to":"string","references":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /mail/accounts/:account_id/signatures

Create signature

Handled by api_create_signature
Parameters
account_id string · path
required
Body · CreateSignatureapplication/json
name string · min length: 1 · max length: 100
required
body_html string · max length: 40000
required
is_default
propertyName anything
Responses
200Successful Response
POST /mail/accounts/example/signatures
1curl -X POST "http://localhost:8000/mail/accounts/example/signatures" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","body_html":"string","is_default":null}'
1fetch("http://localhost:8000/mail/accounts/example/signatures", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "body_html": "string",
7 "is_default": null
8}),
9})
10 .then((res) => res.json())
11 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/mail/accounts/example/signatures",
5 json={"name":"string","body_html":"string","is_default":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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.

Handled by api_create_mail_image
Parameters
account_id string · path
required
Responses
200Successful Response
POST /mail/accounts/example/images
1curl -X POST "http://localhost:8000/mail/accounts/example/images"
1fetch("http://localhost:8000/mail/accounts/example/images", { method: "POST" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.post("http://localhost:8000/mail/accounts/example/images")
4print(response.json())
200 Example Response
No Body
POST /mail/accounts/:account_id/filters

Create filter

Handled by api_create_filter
Parameters
account_id string · path
required
Body · CreateFilterapplication/json
name string · min length: 1 · max length: 200
required
conditions object
required
actions object
required
propertyName anything
Responses
200Successful Response
POST /mail/accounts/example/filters
1curl -X POST "http://localhost:8000/mail/accounts/example/filters" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","conditions":{"from_address":"string","to_address":"string","subject_contains":"string","has_attachment":null},"actions":{"move_to":"string","mark_read":null,"star":null,"archive":null}}'
1fetch("http://localhost:8000/mail/accounts/example/filters", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "conditions": {
7 "from_address": "string",
8 "to_address": "string",
9 "subject_contains": "string",
10 "has_attachment": null
11 },
12 "actions": {
13 "move_to": "string",
14 "mark_read": null,
15 "star": null,
16 "archive": null
17 }
18}),
19})
20 .then((res) => res.json())
21 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/mail/accounts/example/filters",
5 json={"name":"string","conditions":{"from_address":"string","to_address":"string","subject_contains":"string","has_attachment":null},"actions":{"move_to":"string","mark_read":null,"star":null,"archive":null}},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /mail/accounts/:account_id/blocked-senders

Block a sender

Handled by api_create_blocked_sender
Parameters
account_id string · path
required
Body · CreateBlockedSenderapplication/json
blocked string · min length: 3 · max length: 254
required
propertyName anything
Responses
200Successful Response
POST /mail/accounts/example/blocked-senders
1curl -X POST "http://localhost:8000/mail/accounts/example/blocked-senders" \
2 -H "Content-Type: application/json" \
3 -d '{"blocked":"string"}'
1fetch("http://localhost:8000/mail/accounts/example/blocked-senders", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "blocked": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/mail/accounts/example/blocked-senders",
5 json={"blocked":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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.

Handled by api_verify_domain
Parameters
domain_id string · path
required
Responses
200Successful Response
POST /mail/domains/example/verifications
1curl -X POST "http://localhost:8000/mail/domains/example/verifications"
1fetch("http://localhost:8000/mail/domains/example/verifications", { method: "POST" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.post("http://localhost:8000/mail/domains/example/verifications")
4print(response.json())
200 Example Response
No Body
POST /mail/drafts

Create draft

Handled by api_create_draft
Body · SaveDraftapplication/json
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
Responses
200Successful Response
POST /mail/drafts
1curl -X POST "http://localhost:8000/mail/drafts" \
2 -H "Content-Type: application/json" \
3 -d '{"subject":"string","body_html":"string","recipients":{"to":["user@example.com"],"cc":["user@example.com"],"bcc":["user@example.com"]},"attachments":[{"storage_key":"string","filename":"string","content_type":"string","size":1}],"group_id":"string","account_id":"string","in_reply_to":"string","references":"string","quoted_html":"string"}'
1fetch("http://localhost:8000/mail/drafts", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "subject": "string",
6 "body_html": "string",
7 "recipients": {
8 "to": [
9 "user@example.com"
10 ],
11 "cc": [
12 "user@example.com"
13 ],
14 "bcc": [
15 "user@example.com"
16 ]
17 },
18 "attachments": [
19 {
20 "storage_key": "string",
21 "filename": "string",
22 "content_type": "string",
23 "size": 1
24 }
25 ],
26 "group_id": "string",
27 "account_id": "string",
28 "in_reply_to": "string",
29 "references": "string",
30 "quoted_html": "string"
31}),
32})
33 .then((res) => res.json())
34 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/mail/drafts",
5 json={"subject":"string","body_html":"string","recipients":{"to":["user@example.com"],"cc":["user@example.com"],"bcc":["user@example.com"]},"attachments":[{"storage_key":"string","filename":"string","content_type":"string","size":1}],"group_id":"string","account_id":"string","in_reply_to":"string","references":"string","quoted_html":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /mail/drafts/:draft_id/send

Send draft

Handled by api_send_draft
Parameters
draft_id string · path
required
Body · SendDraftapplication/json
subject string · max length: 998
body_html string
recipients object
propertyName anything
Responses
200Successful Response
POST /mail/drafts/example/send
1curl -X POST "http://localhost:8000/mail/drafts/example/send" \
2 -H "Content-Type: application/json" \
3 -d '{"subject":"string","body_html":"string","recipients":{"to":["user@example.com"],"cc":["user@example.com"],"bcc":["user@example.com"]}}'
1fetch("http://localhost:8000/mail/drafts/example/send", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "subject": "string",
6 "body_html": "string",
7 "recipients": {
8 "to": [
9 "user@example.com"
10 ],
11 "cc": [
12 "user@example.com"
13 ],
14 "bcc": [
15 "user@example.com"
16 ]
17 }
18}),
19})
20 .then((res) => res.json())
21 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/mail/drafts/example/send",
5 json={"subject":"string","body_html":"string","recipients":{"to":["user@example.com"],"cc":["user@example.com"],"bcc":["user@example.com"]}},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /mail/accounts/:account_id/signatures/:signature_id

Update signature

Handled by api_update_signature
Parameters
account_id string · path
required
signature_id string · path
required
Body · UpdateSignatureapplication/json
name string · min length: 1 · max length: 100
body_html string · max length: 40000
is_default
propertyName anything
Responses
200Successful Response
PUT /mail/accounts/example/signatures/example
1curl -X PUT "http://localhost:8000/mail/accounts/example/signatures/example" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","body_html":"string","is_default":null}'
1fetch("http://localhost:8000/mail/accounts/example/signatures/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "body_html": "string",
7 "is_default": null
8}),
9})
10 .then((res) => res.json())
11 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/mail/accounts/example/signatures/example",
5 json={"name":"string","body_html":"string","is_default":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /mail/drafts/:draft_id

Save draft

Handled by api_save_draft
Parameters
draft_id string · path
required
Body · SaveDraftapplication/json
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
Responses
200Successful Response
PUT /mail/drafts/example
1curl -X PUT "http://localhost:8000/mail/drafts/example" \
2 -H "Content-Type: application/json" \
3 -d '{"subject":"string","body_html":"string","recipients":{"to":["user@example.com"],"cc":["user@example.com"],"bcc":["user@example.com"]},"attachments":[{"storage_key":"string","filename":"string","content_type":"string","size":1}],"group_id":"string","account_id":"string","in_reply_to":"string","references":"string","quoted_html":"string"}'
1fetch("http://localhost:8000/mail/drafts/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "subject": "string",
6 "body_html": "string",
7 "recipients": {
8 "to": [
9 "user@example.com"
10 ],
11 "cc": [
12 "user@example.com"
13 ],
14 "bcc": [
15 "user@example.com"
16 ]
17 },
18 "attachments": [
19 {
20 "storage_key": "string",
21 "filename": "string",
22 "content_type": "string",
23 "size": 1
24 }
25 ],
26 "group_id": "string",
27 "account_id": "string",
28 "in_reply_to": "string",
29 "references": "string",
30 "quoted_html": "string"
31}),
32})
33 .then((res) => res.json())
34 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/mail/drafts/example",
5 json={"subject":"string","body_html":"string","recipients":{"to":["user@example.com"],"cc":["user@example.com"],"bcc":["user@example.com"]},"attachments":[{"storage_key":"string","filename":"string","content_type":"string","size":1}],"group_id":"string","account_id":"string","in_reply_to":"string","references":"string","quoted_html":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /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.

Handled by api_rotate_outbox_key
Parameters
mailbox_id string · path
required
key_id string · path
required
Responses
200Successful Response
PUT /mail/mailboxes/example/outbox-keys/example/secret
1curl -X PUT "http://localhost:8000/mail/mailboxes/example/outbox-keys/example/secret"
1fetch("http://localhost:8000/mail/mailboxes/example/outbox-keys/example/secret", { method: "PUT" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.put("http://localhost:8000/mail/mailboxes/example/outbox-keys/example/secret")
4print(response.json())
200 Example Response
No Body
POST /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).

Handled by api_create_exchange
Body · CreateExchangeapplication/json
to array
required
cc array
bcc array
subject string · max length: 998
required
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
Responses
200Successful Response
POST /exchanges
1curl -X POST "http://localhost:8000/exchanges" \
2 -H "Content-Type: application/json" \
3 -d '{"to":["user@example.com"],"cc":["user@example.com"],"bcc":["user@example.com"],"subject":"string","html":"string","text":"string","from_name":"string","reply_to":"user@example.com","attachments":[{"filename":"string","content_type":"string","content_base64":"string"}],"in_reply_to":"string","references":"string"}'
1fetch("http://localhost:8000/exchanges", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "to": [
6 "user@example.com"
7 ],
8 "cc": [
9 "user@example.com"
10 ],
11 "bcc": [
12 "user@example.com"
13 ],
14 "subject": "string",
15 "html": "string",
16 "text": "string",
17 "from_name": "string",
18 "reply_to": "user@example.com",
19 "attachments": [
20 {
21 "filename": "string",
22 "content_type": "string",
23 "content_base64": "string"
24 }
25 ],
26 "in_reply_to": "string",
27 "references": "string"
28}),
29})
30 .then((res) => res.json())
31 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/exchanges",
5 json={"to":["user@example.com"],"cc":["user@example.com"],"bcc":["user@example.com"],"subject":"string","html":"string","text":"string","from_name":"string","reply_to":"user@example.com","attachments":[{"filename":"string","content_type":"string","content_base64":"string"}],"in_reply_to":"string","references":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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.

Handled by api_mint_outbox_key
Parameters
mailbox_id string · path
required
Body · MintOutboxKeyapplication/json
name string · min length: 1 · max length: 100
required
expires_at string · max length: 64
propertyName anything
Responses
200Successful Response
POST /mail/mailboxes/example/outbox-keys
1curl -X POST "http://localhost:8000/mail/mailboxes/example/outbox-keys" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","expires_at":"string"}'
1fetch("http://localhost:8000/mail/mailboxes/example/outbox-keys", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "expires_at": "string"
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/mail/mailboxes/example/outbox-keys",
5 json={"name":"string","expires_at":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /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.

Handled by api_update_outbox_key
Parameters
mailbox_id string · path
required
key_id string · path
required
Body · UpdateOutboxKeyapplication/json
name string · min length: 1 · max length: 100
status string
propertyName anything
Responses
200Successful Response
PUT /mail/mailboxes/example/outbox-keys/example
1curl -X PUT "http://localhost:8000/mail/mailboxes/example/outbox-keys/example" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","status":"string"}'
1fetch("http://localhost:8000/mail/mailboxes/example/outbox-keys/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "status": "string"
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/mail/mailboxes/example/outbox-keys/example",
5 json={"name":"string","status":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /mail/domains/:domain_id

Set domain catch-all

Set/clear the wildcard catch-all address for a domain.

Handled by api_update_domain
Parameters
domain_id string · path
required
Body · SetCatchAllapplication/json
catch_all_to string · max length: 254
required
propertyName anything
Responses
200Successful Response
PATCH /mail/domains/example
1curl -X PATCH "http://localhost:8000/mail/domains/example" \
2 -H "Content-Type: application/json" \
3 -d '{"catch_all_to":"string"}'
1fetch("http://localhost:8000/mail/domains/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "catch_all_to": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/mail/domains/example",
5 json={"catch_all_to":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /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.

Handled by api_assign_mailbox
Parameters
mailbox_id string · path
required
Body · AssignMailboxapplication/json
member_mrn string · max length: 200
required
propertyName anything
Responses
200Successful Response
PATCH /mail/mailboxes/example
1curl -X PATCH "http://localhost:8000/mail/mailboxes/example" \
2 -H "Content-Type: application/json" \
3 -d '{"member_mrn":"string"}'
1fetch("http://localhost:8000/mail/mailboxes/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "member_mrn": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/mail/mailboxes/example",
5 json={"member_mrn":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /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.

Handled by api_update_group_member
Parameters
group_id string · path
required
member_id string · path
required
Body · UpdateGroupMemberapplication/json
role string
required
propertyName anything
Responses
200Successful Response
PATCH /mail/groups/example/members/example
1curl -X PATCH "http://localhost:8000/mail/groups/example/members/example" \
2 -H "Content-Type: application/json" \
3 -d '{"role":"string"}'
1fetch("http://localhost:8000/mail/groups/example/members/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "role": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/mail/groups/example/members/example",
5 json={"role":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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.

Handled by api_add_domain
Body · AddDomainapplication/json
domain string · min length: 3 · max length: 253
required
propertyName anything
Responses
200Successful Response
POST /mail/domains
1curl -X POST "http://localhost:8000/mail/domains" \
2 -H "Content-Type: application/json" \
3 -d '{"domain":"string"}'
1fetch("http://localhost:8000/mail/domains", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "domain": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/mail/domains",
5 json={"domain":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /mail/mailboxes

Provision a mailbox

Handled by api_provision_mailbox
Body · ProvisionMailboxapplication/json
local_part string · min length: 1 · max length: 64
required
member_mrn string · max length: 200
display_name string · max length: 200
quota_mb integer · min: 10 · max: 51200
propertyName anything
Responses
200Successful Response
POST /mail/mailboxes
1curl -X POST "http://localhost:8000/mail/mailboxes" \
2 -H "Content-Type: application/json" \
3 -d '{"local_part":"string","member_mrn":"string","display_name":"string","quota_mb":1}'
1fetch("http://localhost:8000/mail/mailboxes", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "local_part": "string",
6 "member_mrn": "string",
7 "display_name": "string",
8 "quota_mb": 1
9}),
10})
11 .then((res) => res.json())
12 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/mail/mailboxes",
5 json={"local_part":"string","member_mrn":"string","display_name":"string","quota_mb":1},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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.

Handled by api_bulk_provision_mailboxes
Body · BulkProvisionMailboxesapplication/json
domain_id string · min length: 1 · max length: 64
required
mailboxes array
required
propertyName anything
Responses
200Successful Response
POST /mail/mailboxes/bulk
1curl -X POST "http://localhost:8000/mail/mailboxes/bulk" \
2 -H "Content-Type: application/json" \
3 -d '{"domain_id":"string","mailboxes":[{"local_part":"string","member_mrn":"string"}]}'
1fetch("http://localhost:8000/mail/mailboxes/bulk", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "domain_id": "string",
6 "mailboxes": [
7 {
8 "local_part": "string",
9 "member_mrn": "string"
10 }
11 ]
12}),
13})
14 .then((res) => res.json())
15 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/mail/mailboxes/bulk",
5 json={"domain_id":"string","mailboxes":[{"local_part":"string","member_mrn":"string"}]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /mail/imports

Import an exported mailbox

Handled by api_create_import
Body · CreateImportapplication/json
mailbox_id string · min length: 1 · max length: 64
required
storage_key string · min length: 1 · max length: 1024
required
filename string · min length: 1 · max length: 255
required
propertyName anything
Responses
200Successful Response
POST /mail/imports
1curl -X POST "http://localhost:8000/mail/imports" \
2 -H "Content-Type: application/json" \
3 -d '{"mailbox_id":"string","storage_key":"string","filename":"string"}'
1fetch("http://localhost:8000/mail/imports", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "mailbox_id": "string",
6 "storage_key": "string",
7 "filename": "string"
8}),
9})
10 .then((res) => res.json())
11 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/mail/imports",
5 json={"mailbox_id":"string","storage_key":"string","filename":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /mail/groups

Create group mailbox

Handled by api_create_group
Body · CreateGroupapplication/json
name string · min length: 1 · max length: 120
required
local_part string · min length: 1 · max length: 64
required
domain_id string · min length: 1 · max length: 64
aliases array
member_mrns array
propertyName anything
Responses
200Successful Response
POST /mail/groups
1curl -X POST "http://localhost:8000/mail/groups" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","local_part":"string","domain_id":"string","aliases":["string"],"member_mrns":["string"]}'
1fetch("http://localhost:8000/mail/groups", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "local_part": "string",
7 "domain_id": "string",
8 "aliases": [
9 "string"
10 ],
11 "member_mrns": [
12 "string"
13 ]
14}),
15})
16 .then((res) => res.json())
17 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/mail/groups",
5 json={"name":"string","local_part":"string","domain_id":"string","aliases":["string"],"member_mrns":["string"]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /mail/groups/:group_id/members

Add group member

Handled by api_add_group_member
Parameters
group_id string · path
required
Body · AddGroupMemberapplication/json
member_mrn string · min length: 1 · max length: 200
required
role string
propertyName anything
Responses
200Successful Response
POST /mail/groups/example/members
1curl -X POST "http://localhost:8000/mail/groups/example/members" \
2 -H "Content-Type: application/json" \
3 -d '{"member_mrn":"string","role":"string"}'
1fetch("http://localhost:8000/mail/groups/example/members", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "member_mrn": "string",
6 "role": "string"
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/mail/groups/example/members",
5 json={"member_mrn":"string","role":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /demo-requests

Request a demo

POST /demo-requests — public lead capture for "Book a demo" (no auth).

Handled by create_demo_request
Body · DemoRequestapplication/json
name string · min length: 1 · max length: 120
required
work_email string · min length: 1 · email
required
slot string · min length: 1 · max length: 40
required
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
Responses
200Successful Response
POST /demo-requests
1curl -X POST "http://localhost:8000/demo-requests" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","work_email":"user@example.com","slot":"string","company":"string","team_size":"string","message":"string","timezone":"string","website":"string"}'
1fetch("http://localhost:8000/demo-requests", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "work_email": "user@example.com",
7 "slot": "string",
8 "company": "string",
9 "team_size": "string",
10 "message": "string",
11 "timezone": "string",
12 "website": "string"
13}),
14})
15 .then((res) => res.json())
16 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/demo-requests",
5 json={"name":"string","work_email":"user@example.com","slot":"string","company":"string","team_size":"string","message":"string","timezone":"string","website":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
GET /me undocumented

/me

Handled by me
Responses
200Successful Response
GET /me
1curl "http://localhost:8000/me"
1fetch("http://localhost:8000/me")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/me")
4print(response.json())
200 Example Response
No Body
GET /me/notification-preferences undocumented

/me/notification-preferences

Handled by api_get_notification_prefs
Responses
200Successful Response
GET /me/notification-preferences
1curl "http://localhost:8000/me/notification-preferences"
1fetch("http://localhost:8000/me/notification-preferences")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/me/notification-preferences")
4print(response.json())
200 Example Response
No Body
GET /media/:collection undocumented

/media/:collection

GET /media/:collection — trending by default, search when ?q= is set.

Handled by browse
Parameters
collection string · path
required
Responses
200Successful Response
GET /media/example
1curl "http://localhost:8000/media/example"
1fetch("http://localhost:8000/media/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/media/example")
4print(response.json())
200 Example Response
No Body
GET /media/:collection/categories undocumented

/media/:collection/categories

GET /media/:collection/categories — the suggestion chips above the grid.

Handled by categories
Parameters
collection string · path
required
Responses
200Successful Response
GET /media/example/categories
1curl "http://localhost:8000/media/example/categories"
1fetch("http://localhost:8000/media/example/categories")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/media/example/categories")
4print(response.json())
200 Example Response
No Body
POST /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.

Handled by create_share
Parameters
collection string · path
required
Body · CreateShareapplication/json
slug string · min length: 1 · max length: 200
required
propertyName anything
Responses
200Successful Response
POST /media/example/shares
1curl -X POST "http://localhost:8000/media/example/shares" \
2 -H "Content-Type: application/json" \
3 -d '{"slug":"string"}'
1fetch("http://localhost:8000/media/example/shares", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "slug": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/media/example/shares",
5 json={"slug":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
DELETE /meetings/:id undocumented

/meetings/:id

Handled by api_delete_meeting
Parameters
id string · path
required
Responses
200Successful Response
DELETE /meetings/example
1curl -X DELETE "http://localhost:8000/meetings/example"
1fetch("http://localhost:8000/meetings/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/meetings/example")
4print(response.json())
200 Example Response
No Body
DELETE /meetings/:id/attendees/:attendee_id undocumented

/meetings/:id/attendees/:attendee_id

Handled by api_remove_attendee
Parameters
id string · path
required
attendee_id string · path
required
Responses
200Successful Response
DELETE /meetings/example/attendees/example
1curl -X DELETE "http://localhost:8000/meetings/example/attendees/example"
1fetch("http://localhost:8000/meetings/example/attendees/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/meetings/example/attendees/example")
4print(response.json())
200 Example Response
No Body
GET /meetings undocumented

/meetings

Handled by api_list_meetings
Responses
200Successful Response
GET /meetings
1curl "http://localhost:8000/meetings"
1fetch("http://localhost:8000/meetings")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/meetings")
4print(response.json())
200 Example Response
No Body
GET /meetings/:id/attendees undocumented

/meetings/:id/attendees

Handled by api_list_attendees
Parameters
id string · path
required
Responses
200Successful Response
GET /meetings/example/attendees
1curl "http://localhost:8000/meetings/example/attendees"
1fetch("http://localhost:8000/meetings/example/attendees")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/meetings/example/attendees")
4print(response.json())
200 Example Response
No Body
PATCH /meetings/:id

Update a meeting

Handled by api_update_meeting
Parameters
id string · path
required
Body · UpdateMeetingapplication/json
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
Responses
200Successful Response
PATCH /meetings/example
1curl -X PATCH "http://localhost:8000/meetings/example" \
2 -H "Content-Type: application/json" \
3 -d '{"title":"string","description":"string","start_datetime":"string","end_datetime":"string","timezone":"string","is_all_day":null,"color":"string","type":"string","status":"string","recurrence_rule":"string","visibility":"string"}'
1fetch("http://localhost:8000/meetings/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "title": "string",
6 "description": "string",
7 "start_datetime": "string",
8 "end_datetime": "string",
9 "timezone": "string",
10 "is_all_day": null,
11 "color": "string",
12 "type": "string",
13 "status": "string",
14 "recurrence_rule": "string",
15 "visibility": "string"
16}),
17})
18 .then((res) => res.json())
19 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/meetings/example",
5 json={"title":"string","description":"string","start_datetime":"string","end_datetime":"string","timezone":"string","is_all_day":null,"color":"string","type":"string","status":"string","recurrence_rule":"string","visibility":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /meetings

Create a meeting

Handled by api_create_meeting
Body · CreateMeetingapplication/json
title string · min length: 1 · max length: 300
required
start_datetime string · min length: 1
required
end_datetime string · min length: 1
required
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
Responses
200Successful Response
POST /meetings
1curl -X POST "http://localhost:8000/meetings" \
2 -H "Content-Type: application/json" \
3 -d '{"title":"string","start_datetime":"string","end_datetime":"string","description":"string","timezone":"string","is_all_day":null,"color":"string","type":"string","status":"string","create_call":null,"recurrence_rule":"string","visibility":"string","attendees":["string"],"external_invitees":[{"email":"user@example.com","name":"string"}]}'
1fetch("http://localhost:8000/meetings", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "title": "string",
6 "start_datetime": "string",
7 "end_datetime": "string",
8 "description": "string",
9 "timezone": "string",
10 "is_all_day": null,
11 "color": "string",
12 "type": "string",
13 "status": "string",
14 "create_call": null,
15 "recurrence_rule": "string",
16 "visibility": "string",
17 "attendees": [
18 "string"
19 ],
20 "external_invitees": [
21 {
22 "email": "user@example.com",
23 "name": "string"
24 }
25 ]
26}),
27})
28 .then((res) => res.json())
29 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/meetings",
5 json={"title":"string","start_datetime":"string","end_datetime":"string","description":"string","timezone":"string","is_all_day":null,"color":"string","type":"string","status":"string","create_call":null,"recurrence_rule":"string","visibility":"string","attendees":["string"],"external_invitees":[{"email":"user@example.com","name":"string"}]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /meetings/:id/attendees

Add someone to a meeting

Handled by api_add_attendee
Parameters
id string · path
required
Body · AddMeetingAttendeeapplication/json
profile_id string · max length: 100
email string · max length: 320
name string · max length: 200
notify_everyone
propertyName anything
Responses
200Successful Response
POST /meetings/example/attendees
1curl -X POST "http://localhost:8000/meetings/example/attendees" \
2 -H "Content-Type: application/json" \
3 -d '{"profile_id":"string","email":"string","name":"string","notify_everyone":null}'
1fetch("http://localhost:8000/meetings/example/attendees", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "profile_id": "string",
6 "email": "string",
7 "name": "string",
8 "notify_everyone": null
9}),
10})
11 .then((res) => res.json())
12 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/meetings/example/attendees",
5 json={"profile_id":"string","email":"string","name":"string","notify_everyone":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /meetings/:id/call undocumented

/meetings/:id/call

Handled by api_create_meeting_call
Parameters
id string · path
required
Responses
200Successful Response
POST /meetings/example/call
1curl -X POST "http://localhost:8000/meetings/example/call"
1fetch("http://localhost:8000/meetings/example/call", { method: "POST" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.post("http://localhost:8000/meetings/example/call")
4print(response.json())
200 Example Response
No Body
PUT /meetings/:id/rsvp

Set your RSVP for a meeting

PUT /meetings/:id/rsvp — the authenticated caller sets their own RSVP.

Handled by api_set_rsvp
Parameters
id string · path
required
Body · Rsvpapplication/json
status
required
propertyName anything
Responses
200Successful Response
PUT /meetings/example/rsvp
1curl -X PUT "http://localhost:8000/meetings/example/rsvp" \
2 -H "Content-Type: application/json" \
3 -d '{"status":null}'
1fetch("http://localhost:8000/meetings/example/rsvp", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "status": null
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/meetings/example/rsvp",
5 json={"status":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
DELETE /members/:member_id undocumented

/members/:member_id

DELETE /accounts/organisation/members/:member_id — Remove a member.

Handled by api_remove_member
Parameters
member_id string · path
required
Responses
200Successful Response
DELETE /members/example
1curl -X DELETE "http://localhost:8000/members/example"
1fetch("http://localhost:8000/members/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/members/example")
4print(response.json())
200 Example Response
No Body
GET /members undocumented

/members

GET /members — Search workspace members by name or email.

Handled by api_search_members
Responses
200Successful Response
GET /members
1curl "http://localhost:8000/members"
1fetch("http://localhost:8000/members")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/members")
4print(response.json())
200 Example Response
No Body
PATCH /members/:member_id undocumented

/members/:member_id

PATCH /accounts/organisation/members/:member_id — Change platform role.

Handled by api_update_member_role
Parameters
member_id string · path
required
Responses
200Successful Response
PATCH /members/example
1curl -X PATCH "http://localhost:8000/members/example"
1fetch("http://localhost:8000/members/example", { method: "PATCH" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.patch("http://localhost:8000/members/example")
4print(response.json())
200 Example Response
No Body
POST /members

Invite member

POST /accounts/organisation/members — Invite a member.

Handled by api_invite_member
Body · InviteMemberapplication/json
email string · min length: 1 · email
required
full_name string · max length: 200
role
propertyName anything
Responses
200Successful Response
POST /members
1curl -X POST "http://localhost:8000/members" \
2 -H "Content-Type: application/json" \
3 -d '{"email":"user@example.com","full_name":"string","role":null}'
1fetch("http://localhost:8000/members", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "email": "user@example.com",
6 "full_name": "string",
7 "role": null
8}),
9})
10 .then((res) => res.json())
11 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/members",
5 json={"email":"user@example.com","full_name":"string","role":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /members/bulk

Bulk invite members

POST /members/bulk — Invite multiple members at once.

Handled by api_bulk_invite_members
Body · BulkInviteMembersapplication/json
members array
required
propertyName anything
Responses
200Successful Response
POST /members/bulk
1curl -X POST "http://localhost:8000/members/bulk" \
2 -H "Content-Type: application/json" \
3 -d '{"members":[{"first_name":"string","last_name":"string","email":"user@example.com","role":null}]}'
1fetch("http://localhost:8000/members/bulk", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "members": [
6 {
7 "first_name": "string",
8 "last_name": "string",
9 "email": "user@example.com",
10 "role": null
11 }
12 ]
13}),
14})
15 .then((res) => res.json())
16 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/members/bulk",
5 json={"members":[{"first_name":"string","last_name":"string","email":"user@example.com","role":null}]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /members/:member_id/invitations undocumented

/members/:member_id/invitations

POST /members/:member_id/invitations — Re-invite a member with a fresh token.

Handled by api_reinvite_member
Parameters
member_id string · path
required
Responses
200Successful Response
POST /members/example/invitations
1curl -X POST "http://localhost:8000/members/example/invitations"
1fetch("http://localhost:8000/members/example/invitations", { method: "POST" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.post("http://localhost:8000/members/example/invitations")
4print(response.json())
200 Example Response
No Body
POST /members/:member_id/password-resets undocumented

/members/:member_id/password-resets

POST /members/:member_id/password-resets — Send a 'Set Your Password' email.

Handled by api_send_set_password
Parameters
member_id string · path
required
Responses
200Successful Response
POST /members/example/password-resets
1curl -X POST "http://localhost:8000/members/example/password-resets"
1fetch("http://localhost:8000/members/example/password-resets", { method: "POST" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.post("http://localhost:8000/members/example/password-resets")
4print(response.json())
200 Example Response
No Body
POST /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.

Handled by api_force_logout_member
Parameters
member_id string · path
required
Body · ForceLogoutapplication/json
action
required
propertyName anything
Responses
200Successful Response
POST /members/example/sessions
1curl -X POST "http://localhost:8000/members/example/sessions" \
2 -H "Content-Type: application/json" \
3 -d '{"action":null}'
1fetch("http://localhost:8000/members/example/sessions", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "action": null
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/members/example/sessions",
5 json={"action":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /chats/:id/messages/:msg_id

Edit a message

PATCH /chats/:id/messages/:msg_id — edit a message.

Handled by api_edit_message
Parameters
id string · path
required
msg_id string · path
required
Body · EditMessageapplication/json
content string · min length: 1 · max length: 10000
required
propertyName anything
Responses
200Successful Response
PATCH /chats/example/messages/example
1curl -X PATCH "http://localhost:8000/chats/example/messages/example" \
2 -H "Content-Type: application/json" \
3 -d '{"content":"string"}'
1fetch("http://localhost:8000/chats/example/messages/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "content": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/chats/example/messages/example",
5 json={"content":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /calls/:id/messages

Send a chat message

Handled by api_create_message
Parameters
id string · path
required
Body · CreateMessageapplication/json
content string · min length: 1 · max length: 2000
required
propertyName anything
Responses
200Successful Response
POST /calls/example/messages
1curl -X POST "http://localhost:8000/calls/example/messages" \
2 -H "Content-Type: application/json" \
3 -d '{"content":"string"}'
1fetch("http://localhost:8000/calls/example/messages", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "content": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/calls/example/messages",
5 json={"content":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /chats/:id/messages

Send a message

POST /chats/:id/messages — send a message.

Handled by api_send_message
Parameters
id string · path
required
Body · SendMessageapplication/json
to array
required
cc array
bcc array
subject string · max length: 998
required
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
Responses
200Successful Response
POST /chats/example/messages
1curl -X POST "http://localhost:8000/chats/example/messages" \
2 -H "Content-Type: application/json" \
3 -d '{"to":[{"email":"user@example.com","name":"string"}],"cc":[{"email":"user@example.com","name":"string"}],"bcc":[{"email":"user@example.com","name":"string"}],"subject":"string","body_text":"string","body_html":"string","is_draft":null,"signature_id":"string","attachments":[{"storage_key":"string","filename":"string","content_type":"string","size":1}],"in_reply_to":"string","references":"string"}'
1fetch("http://localhost:8000/chats/example/messages", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "to": [
6 {
7 "email": "user@example.com",
8 "name": "string"
9 }
10 ],
11 "cc": [
12 {
13 "email": "user@example.com",
14 "name": "string"
15 }
16 ],
17 "bcc": [
18 {
19 "email": "user@example.com",
20 "name": "string"
21 }
22 ],
23 "subject": "string",
24 "body_text": "string",
25 "body_html": "string",
26 "is_draft": null,
27 "signature_id": "string",
28 "attachments": [
29 {
30 "storage_key": "string",
31 "filename": "string",
32 "content_type": "string",
33 "size": 1
34 }
35 ],
36 "in_reply_to": "string",
37 "references": "string"
38}),
39})
40 .then((res) => res.json())
41 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/chats/example/messages",
5 json={"to":[{"email":"user@example.com","name":"string"}],"cc":[{"email":"user@example.com","name":"string"}],"bcc":[{"email":"user@example.com","name":"string"}],"subject":"string","body_text":"string","body_html":"string","is_draft":null,"signature_id":"string","attachments":[{"storage_key":"string","filename":"string","content_type":"string","size":1}],"in_reply_to":"string","references":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
DELETE /notifications/:id undocumented

/notifications/:id

Hard-delete a single notification.

Handled by delete_notification
Parameters
id string · path
required
Responses
200Successful Response
DELETE /notifications/example
1curl -X DELETE "http://localhost:8000/notifications/example"
1fetch("http://localhost:8000/notifications/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/notifications/example")
4print(response.json())
200 Example Response
No Body
GET /notifications undocumented

/notifications

Handled by list_notifications
Responses
200Successful Response
GET /notifications
1curl "http://localhost:8000/notifications"
1fetch("http://localhost:8000/notifications")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/notifications")
4print(response.json())
200 Example Response
No Body
GET /notifications/unread-count undocumented

/notifications/unread-count

Handled by unread_count
Responses
200Successful Response
GET /notifications/unread-count
1curl "http://localhost:8000/notifications/unread-count"
1fetch("http://localhost:8000/notifications/unread-count")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/notifications/unread-count")
4print(response.json())
200 Example Response
No Body
PATCH /notifications/:id undocumented

/notifications/:id

Mark a single notification as read.

Handled by mark_read
Parameters
id string · path
required
Responses
200Successful Response
PATCH /notifications/example
1curl -X PATCH "http://localhost:8000/notifications/example"
1fetch("http://localhost:8000/notifications/example", { method: "PATCH" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.patch("http://localhost:8000/notifications/example")
4print(response.json())
200 Example Response
No Body
PATCH /notifications undocumented

/notifications

Mark all notifications as read for the authenticated member.

Handled by mark_all_read
Responses
200Successful Response
PATCH /notifications
1curl -X PATCH "http://localhost:8000/notifications"
1fetch("http://localhost:8000/notifications", { method: "PATCH" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.patch("http://localhost:8000/notifications")
4print(response.json())
200 Example Response
No Body
GET /onboarding/handle-check undocumented

/onboarding/handle-check

GET /onboarding/handle-check?handle=xxx — Check if a workspace handle is available.

Handled by check_handle
Responses
200Successful Response
GET /onboarding/handle-check
1curl "http://localhost:8000/onboarding/handle-check"
1fetch("http://localhost:8000/onboarding/handle-check")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/onboarding/handle-check")
4print(response.json())
200 Example Response
No Body
POST /onboarding/payments

Capture onboarding payment

POST /accounts/onboarding/payment — Add card via Flutterwave v4.

Handled by capture_payment
Body · CapturePaymentapplication/json
card_number string · min length: 13 · max length: 19
required
expiry_month string · min length: 1 · max length: 2
required
expiry_year string · min length: 2 · max length: 4
required
cvv string · min length: 3 · max length: 4
required
propertyName anything
Responses
200Successful Response
POST /onboarding/payments
1curl -X POST "http://localhost:8000/onboarding/payments" \
2 -H "Content-Type: application/json" \
3 -d '{"card_number":"string","expiry_month":"string","expiry_year":"string","cvv":"string"}'
1fetch("http://localhost:8000/onboarding/payments", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "card_number": "string",
6 "expiry_month": "string",
7 "expiry_year": "string",
8 "cvv": "string"
9}),
10})
11 .then((res) => res.json())
12 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/onboarding/payments",
5 json={"card_number":"string","expiry_month":"string","expiry_year":"string","cvv":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /onboarding/steps undocumented

/onboarding/steps

POST /accounts/onboarding/skip-payment — Skip payment step.

Handled by skip_payment
Responses
200Successful Response
POST /onboarding/steps
1curl -X POST "http://localhost:8000/onboarding/steps"
1fetch("http://localhost:8000/onboarding/steps", { method: "POST" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.post("http://localhost:8000/onboarding/steps")
4print(response.json())
200 Example Response
No Body
POST /onboarding/invitations

Send onboarding invites

POST /accounts/onboarding/invites — Invite collaborators.

Handled by send_invites
Body · SendInvitesapplication/json
emails array
required
propertyName anything
Responses
200Successful Response
POST /onboarding/invitations
1curl -X POST "http://localhost:8000/onboarding/invitations" \
2 -H "Content-Type: application/json" \
3 -d '{"emails":["string"]}'
1fetch("http://localhost:8000/onboarding/invitations", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "emails": [
6 "string"
7 ]
8}),
9})
10 .then((res) => res.json())
11 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/onboarding/invitations",
5 json={"emails":["string"]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /onboarding/completions undocumented

/onboarding/completions

POST /accounts/onboarding/complete — Mark workspace as onboarded.

Handled by complete_onboarding
Responses
200Successful Response
POST /onboarding/completions
1curl -X POST "http://localhost:8000/onboarding/completions"
1fetch("http://localhost:8000/onboarding/completions", { method: "POST" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.post("http://localhost:8000/onboarding/completions")
4print(response.json())
200 Example Response
No Body
PUT /onboarding/profile

Setup onboarding profile

PUT /accounts/onboarding/profile — Update avatar and workspace theme.

Handled by setup_profile
Body · SetupProfileapplication/json
avatar_url string · max length: 2048
propertyName anything
Responses
200Successful Response
PUT /onboarding/profile
1curl -X PUT "http://localhost:8000/onboarding/profile" \
2 -H "Content-Type: application/json" \
3 -d '{"avatar_url":"string"}'
1fetch("http://localhost:8000/onboarding/profile", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "avatar_url": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/onboarding/profile",
5 json={"avatar_url":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /onboarding/handle

Set workspace handle

PUT /onboarding/handle — Set the workspace handle and display name.

Handled by set_handle
Body · SetHandleapplication/json
handle string · min length: 3 · max length: 30
required
name string · min length: 1 · max length: 200
propertyName anything
Responses
200Successful Response
PUT /onboarding/handle
1curl -X PUT "http://localhost:8000/onboarding/handle" \
2 -H "Content-Type: application/json" \
3 -d '{"handle":"string","name":"string"}'
1fetch("http://localhost:8000/onboarding/handle", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "handle": "string",
6 "name": "string"
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/onboarding/handle",
5 json={"handle":"string","name":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
GET /online undocumented

/online

List workspace members who are currently online.

Handled by api_online_members
Responses
200Successful Response
GET /online
1curl "http://localhost:8000/online"
1fetch("http://localhost:8000/online")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/online")
4print(response.json())
200 Example Response
No Body
PATCH /finance/orders/:entry_id

Transition an order

Handled by api_patch_order
Parameters
entry_id string · path
required
Body · UpdateOrderStatusapplication/json
status
required
propertyName anything
Responses
200Successful Response
PATCH /finance/orders/example
1curl -X PATCH "http://localhost:8000/finance/orders/example" \
2 -H "Content-Type: application/json" \
3 -d '{"status":null}'
1fetch("http://localhost:8000/finance/orders/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "status": null
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/finance/orders/example",
5 json={"status":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /finance/orders

Create an order

Handled by api_create_order
Body · CreateOrderapplication/json
date string · min length: 10
required
items array
contact_mrn string
company_mrn string
currency
required
exchange_rate number
memo string · max length: 5000
tags array
sources array
adjustments array
idempotency_key string · max length: 100
propertyName anything
Responses
200Successful Response
POST /finance/orders
1curl -X POST "http://localhost:8000/finance/orders" \
2 -H "Content-Type: application/json" \
3 -d '{"date":"string","items":[{"description":"string","quantity":1.5,"unit_price":1.5,"discount":1.5,"amount":1.5,"account_code":"string","product_mrn":"string","taxes":[{"name":"string","rate":1.5,"amount":1.5,"reverse_charge":null}]}],"contact_mrn":"string","company_mrn":"string","currency":null,"exchange_rate":1.5,"memo":"string","tags":["string"],"sources":["string"],"adjustments":[{"label":"string","type":null,"value":1.5,"amount":1.5,"account_code":"string"}],"idempotency_key":"string"}'
1fetch("http://localhost:8000/finance/orders", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "date": "string",
6 "items": [
7 {
8 "description": "string",
9 "quantity": 1.5,
10 "unit_price": 1.5,
11 "discount": 1.5,
12 "amount": 1.5,
13 "account_code": "string",
14 "product_mrn": "string",
15 "taxes": [
16 {
17 "name": "string",
18 "rate": 1.5,
19 "amount": 1.5,
20 "reverse_charge": null
21 }
22 ]
23 }
24 ],
25 "contact_mrn": "string",
26 "company_mrn": "string",
27 "currency": null,
28 "exchange_rate": 1.5,
29 "memo": "string",
30 "tags": [
31 "string"
32 ],
33 "sources": [
34 "string"
35 ],
36 "adjustments": [
37 {
38 "label": "string",
39 "type": null,
40 "value": 1.5,
41 "amount": 1.5,
42 "account_code": "string"
43 }
44 ],
45 "idempotency_key": "string"
46}),
47})
48 .then((res) => res.json())
49 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/finance/orders",
5 json={"date":"string","items":[{"description":"string","quantity":1.5,"unit_price":1.5,"discount":1.5,"amount":1.5,"account_code":"string","product_mrn":"string","taxes":[{"name":"string","rate":1.5,"amount":1.5,"reverse_charge":null}]}],"contact_mrn":"string","company_mrn":"string","currency":null,"exchange_rate":1.5,"memo":"string","tags":["string"],"sources":["string"],"adjustments":[{"label":"string","type":null,"value":1.5,"amount":1.5,"account_code":"string"}],"idempotency_key":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /finance/orders/:entry_id/fulfillments

Record a fulfillment

Record a fulfillment — auto-creates a draft invoice with selected lines.

Handled by api_create_fulfillment
Parameters
entry_id string · path
required
Body · CreateFulfillmentapplication/json
date string · min length: 10
required
lines array
required
memo string · max length: 2000
propertyName anything
Responses
200Successful Response
POST /finance/orders/example/fulfillments
1curl -X POST "http://localhost:8000/finance/orders/example/fulfillments" \
2 -H "Content-Type: application/json" \
3 -d '{"date":"string","lines":[{"item_index":1,"quantity":1.5}],"memo":"string"}'
1fetch("http://localhost:8000/finance/orders/example/fulfillments", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "date": "string",
6 "lines": [
7 {
8 "item_index": 1,
9 "quantity": 1.5
10 }
11 ],
12 "memo": "string"
13}),
14})
15 .then((res) => res.json())
16 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/finance/orders/example/fulfillments",
5 json={"date":"string","lines":[{"item_index":1,"quantity":1.5}],"memo":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /finance/orders/:entry_id

Update a draft order

Handled by api_update_order
Parameters
entry_id string · path
required
Body · UpdateOrderapplication/json
status
required
fulfillment object
propertyName anything
Responses
200Successful Response
PUT /finance/orders/example
1curl -X PUT "http://localhost:8000/finance/orders/example" \
2 -H "Content-Type: application/json" \
3 -d '{"status":null,"fulfillment":{"carrier":"string","tracking_ref":"string","note":"string"}}'
1fetch("http://localhost:8000/finance/orders/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "status": null,
6 "fulfillment": {
7 "carrier": "string",
8 "tracking_ref": "string",
9 "note": "string"
10 }
11}),
12})
13 .then((res) => res.json())
14 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/finance/orders/example",
5 json={"status":null,"fulfillment":{"carrier":"string","tracking_ref":"string","note":"string"}},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /organisations/:org_id

Update organisation

PUT /accounts/organisation — Update org details.

Handled by api_update_org
Parameters
org_id string · path
required
Body · UpdateOrgapplication/json
name string · min length: 1 · max length: 200
email_domain string
industry string
size string
timezone string · max length: 64
propertyName anything
Responses
200Successful Response
PUT /organisations/example
1curl -X PUT "http://localhost:8000/organisations/example" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","email_domain":"string","industry":"string","size":"string","timezone":"string"}'
1fetch("http://localhost:8000/organisations/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "email_domain": "string",
7 "industry": "string",
8 "size": "string",
9 "timezone": "string"
10}),
11})
12 .then((res) => res.json())
13 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/organisations/example",
5 json={"name":"string","email_domain":"string","industry":"string","size":"string","timezone":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /ptos

Request time off

Handled by api_create_pto
Body · CreatePtoapplication/json
policy_id string · min length: 1
required
start_date string · min length: 1
required
end_date string · min length: 1
required
half_day
reason string · max length: 1000
propertyName anything
Responses
200Successful Response
POST /ptos
1curl -X POST "http://localhost:8000/ptos" \
2 -H "Content-Type: application/json" \
3 -d '{"policy_id":"string","start_date":"string","end_date":"string","half_day":null,"reason":"string"}'
1fetch("http://localhost:8000/ptos", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "policy_id": "string",
6 "start_date": "string",
7 "end_date": "string",
8 "half_day": null,
9 "reason": "string"
10}),
11})
12 .then((res) => res.json())
13 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/ptos",
5 json={"policy_id":"string","start_date":"string","end_date":"string","half_day":null,"reason":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /ptos/:id

Update a pending PTO

Handled by api_update_pto
Parameters
id string · path
required
Body · UpdatePtoapplication/json
start_date string · min length: 1
end_date string · min length: 1
half_day
reason string · max length: 1000
propertyName anything
Responses
200Successful Response
PUT /ptos/example
1curl -X PUT "http://localhost:8000/ptos/example" \
2 -H "Content-Type: application/json" \
3 -d '{"start_date":"string","end_date":"string","half_day":null,"reason":"string"}'
1fetch("http://localhost:8000/ptos/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "start_date": "string",
6 "end_date": "string",
7 "half_day": null,
8 "reason": "string"
9}),
10})
11 .then((res) => res.json())
12 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/ptos/example",
5 json={"start_date":"string","end_date":"string","half_day":null,"reason":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /ptos/:id/decision

Approve or deny a PTO

Approve or deny a PTO (manager/admin).

Handled by api_decide_pto
Parameters
id string · path
required
Body · DecidePtoapplication/json
decision
required
note string · max length: 1000
propertyName anything
Responses
200Successful Response
PUT /ptos/example/decision
1curl -X PUT "http://localhost:8000/ptos/example/decision" \
2 -H "Content-Type: application/json" \
3 -d '{"decision":null,"note":"string"}'
1fetch("http://localhost:8000/ptos/example/decision", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "decision": null,
6 "note": "string"
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/ptos/example/decision",
5 json={"decision":null,"note":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
DELETE /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.

Handled by api_empty_trash
Responses
200Successful Response
DELETE /papers/trash
1curl -X DELETE "http://localhost:8000/papers/trash"
1fetch("http://localhost:8000/papers/trash", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/papers/trash")
4print(response.json())
200 Example Response
No Body
DELETE /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.

Handled by api_purge_document
Parameters
document_id string · path
required
Responses
200Successful Response
DELETE /papers/trash/example
1curl -X DELETE "http://localhost:8000/papers/trash/example"
1fetch("http://localhost:8000/papers/trash/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/papers/trash/example")
4print(response.json())
200 Example Response
No Body
DELETE /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.

Handled by api_delete_document
Parameters
document_id string · path
required
Responses
200Successful Response
DELETE /papers/example
1curl -X DELETE "http://localhost:8000/papers/example"
1fetch("http://localhost:8000/papers/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/papers/example")
4print(response.json())
200 Example Response
No Body
DELETE /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).

Handled by api_delete_comment
Parameters
document_id string · path
required
comment_id string · path
required
Responses
200Successful Response
DELETE /papers/example/comments/example
1curl -X DELETE "http://localhost:8000/papers/example/comments/example"
1fetch("http://localhost:8000/papers/example/comments/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/papers/example/comments/example")
4print(response.json())
200 Example Response
No Body
GET /papers undocumented

/papers

GET /papers — list documents for the workspace.

Handled by api_list_documents
Responses
200Successful Response
GET /papers
1curl "http://localhost:8000/papers"
1fetch("http://localhost:8000/papers")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/papers")
4print(response.json())
200 Example Response
No Body
GET /papers/web-images undocumented

/papers/web-images

GET /papers/web-images?q=&page= — search openly-licensed web images.

Handled by api_search_web_images
Responses
200Successful Response
GET /papers/web-images
1curl "http://localhost:8000/papers/web-images"
1fetch("http://localhost:8000/papers/web-images")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/papers/web-images")
4print(response.json())
200 Example Response
No Body
GET /papers/trash undocumented

/papers/trash

GET /papers/trash — documents in the trash that the caller can restore.

Handled by api_list_trash
Responses
200Successful Response
GET /papers/trash
1curl "http://localhost:8000/papers/trash"
1fetch("http://localhost:8000/papers/trash")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/papers/trash")
4print(response.json())
200 Example Response
No Body
GET /papers/:document_id undocumented

/papers/:document_id

GET /papers/:document_id — get a single document with content.

Handled by api_get_document
Parameters
document_id string · path
required
Responses
200Successful Response
GET /papers/example
1curl "http://localhost:8000/papers/example"
1fetch("http://localhost:8000/papers/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/papers/example")
4print(response.json())
200 Example Response
No Body
GET /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).

Handled by api_export_document
Parameters
document_id string · path
required
format string · path
required
Responses
200Successful Response
GET /papers/example/exports/example
1curl "http://localhost:8000/papers/example/exports/example"
1fetch("http://localhost:8000/papers/example/exports/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/papers/example/exports/example")
4print(response.json())
200 Example Response
No Body
GET /papers/:document_id/versions undocumented

/papers/:document_id/versions

GET /papers/:document_id/versions — list version history.

Handled by api_list_versions
Parameters
document_id string · path
required
Responses
200Successful Response
GET /papers/example/versions
1curl "http://localhost:8000/papers/example/versions"
1fetch("http://localhost:8000/papers/example/versions")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/papers/example/versions")
4print(response.json())
200 Example Response
No Body
GET /papers/:document_id/versions/:version_id undocumented

/papers/:document_id/versions/:version_id

GET /papers/:document_id/versions/:version_id — get a single version.

Handled by api_get_version
Parameters
document_id string · path
required
version_id string · path
required
Responses
200Successful Response
GET /papers/example/versions/example
1curl "http://localhost:8000/papers/example/versions/example"
1fetch("http://localhost:8000/papers/example/versions/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/papers/example/versions/example")
4print(response.json())
200 Example Response
No Body
GET /papers/:document_id/comments undocumented

/papers/:document_id/comments

GET /papers/:document_id/comments — list comments for a document.

Handled by api_list_comments
Parameters
document_id string · path
required
Responses
200Successful Response
GET /papers/example/comments
1curl "http://localhost:8000/papers/example/comments"
1fetch("http://localhost:8000/papers/example/comments")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/papers/example/comments")
4print(response.json())
200 Example Response
No Body
GET /papers/:document_id/presence undocumented

/papers/:document_id/presence

GET /papers/:document_id/presence — get active collaborators.

Handled by api_get_presence
Parameters
document_id string · path
required
Responses
200Successful Response
GET /papers/example/presence
1curl "http://localhost:8000/papers/example/presence"
1fetch("http://localhost:8000/papers/example/presence")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/papers/example/presence")
4print(response.json())
200 Example Response
No Body
PATCH /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).

Handled by api_update_document
Parameters
document_id string · path
required
Body · UpdateDocumentapplication/json
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
Responses
200Successful Response
PATCH /papers/example
1curl -X PATCH "http://localhost:8000/papers/example" \
2 -H "Content-Type: application/json" \
3 -d '{"title":"string","icon":"string","icon_type":null,"content":"string","is_starred":null,"page_mode":null,"visibility":null,"page_setup":{"size":null,"orientation":null,"margins":null,"margin_x":1,"margin_y":1,"header_text":"string","footer_text":"string","show_page_numbers":null,"watermark_text":"string"},"deleted":null}'
1fetch("http://localhost:8000/papers/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "title": "string",
6 "icon": "string",
7 "icon_type": null,
8 "content": "string",
9 "is_starred": null,
10 "page_mode": null,
11 "visibility": null,
12 "page_setup": {
13 "size": null,
14 "orientation": null,
15 "margins": null,
16 "margin_x": 1,
17 "margin_y": 1,
18 "header_text": "string",
19 "footer_text": "string",
20 "show_page_numbers": null,
21 "watermark_text": "string"
22 },
23 "deleted": null
24}),
25})
26 .then((res) => res.json())
27 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/papers/example",
5 json={"title":"string","icon":"string","icon_type":null,"content":"string","is_starred":null,"page_mode":null,"visibility":null,"page_setup":{"size":null,"orientation":null,"margins":null,"margin_x":1,"margin_y":1,"header_text":"string","footer_text":"string","show_page_numbers":null,"watermark_text":"string"},"deleted":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /papers/:document_id/versions/:version_id

Name or rename a version

PATCH /papers/:document_id/versions/:version_id — name or rename a version.

Handled by api_update_version
Parameters
document_id string · path
required
version_id string · path
required
Body · UpdateVersionapplication/json
name string · max length: 120
required
propertyName anything
Responses
200Successful Response
PATCH /papers/example/versions/example
1curl -X PATCH "http://localhost:8000/papers/example/versions/example" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string"}'
1fetch("http://localhost:8000/papers/example/versions/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/papers/example/versions/example",
5 json={"name":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /papers/:document_id/comments/:comment_id

Resolve/unresolve comment

PATCH /papers/:document_id/comments/:comment_id — resolve or unresolve.

Handled by api_resolve_comment
Parameters
document_id string · path
required
comment_id string · path
required
Body · ResolveCommentapplication/json
resolved
required
propertyName anything
Responses
200Successful Response
PATCH /papers/example/comments/example
1curl -X PATCH "http://localhost:8000/papers/example/comments/example" \
2 -H "Content-Type: application/json" \
3 -d '{"resolved":null}'
1fetch("http://localhost:8000/papers/example/comments/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "resolved": null
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/papers/example/comments/example",
5 json={"resolved":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /papers

Create a document

POST /papers — create a new document.

Handled by api_create_document
Body · CreateDocumentapplication/json
title string · min length: 1 · max length: 500
required
icon string · max length: 100
icon_type
content string
propertyName anything
Responses
200Successful Response
POST /papers
1curl -X POST "http://localhost:8000/papers" \
2 -H "Content-Type: application/json" \
3 -d '{"title":"string","icon":"string","icon_type":null,"content":"string"}'
1fetch("http://localhost:8000/papers", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "title": "string",
6 "icon": "string",
7 "icon_type": null,
8 "content": "string"
9}),
10})
11 .then((res) => res.json())
12 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/papers",
5 json={"title":"string","icon":"string","icon_type":null,"content":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /papers/imports undocumented

/papers/imports

POST /papers/imports — create a new document from an uploaded .docx/.odt.

Handled by api_import_document
Responses
200Successful Response
POST /papers/imports
1curl -X POST "http://localhost:8000/papers/imports"
1fetch("http://localhost:8000/papers/imports", { method: "POST" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.post("http://localhost:8000/papers/imports")
4print(response.json())
200 Example Response
No Body
POST /papers/:document_id/images undocumented

/papers/:document_id/images

POST /papers/:document_id/images: keep an uploaded image with this document, privately.

Handled by api_upload_image
Parameters
document_id string · path
required
Responses
200Successful Response
POST /papers/example/images
1curl -X POST "http://localhost:8000/papers/example/images"
1fetch("http://localhost:8000/papers/example/images", { method: "POST" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.post("http://localhost:8000/papers/example/images")
4print(response.json())
200 Example Response
No Body
POST /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.

Handled by api_import_image
Parameters
document_id string · path
required
Body · ImportImageapplication/json
url string · min length: 1 · max length: 2000
required
propertyName anything
Responses
200Successful Response
POST /papers/example/image-imports
1curl -X POST "http://localhost:8000/papers/example/image-imports" \
2 -H "Content-Type: application/json" \
3 -d '{"url":"string"}'
1fetch("http://localhost:8000/papers/example/image-imports", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "url": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/papers/example/image-imports",
5 json={"url":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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).

Handled by api_create_version
Parameters
document_id string · path
required
Body · CreateVersionapplication/json
name string · min length: 1 · max length: 120
required
propertyName anything
Responses
200Successful Response
POST /papers/example/versions
1curl -X POST "http://localhost:8000/papers/example/versions" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string"}'
1fetch("http://localhost:8000/papers/example/versions", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/papers/example/versions",
5 json={"name":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /papers/:document_id/comments

Add a comment

POST /papers/:document_id/comments — add a comment.

Handled by api_create_comment
Parameters
document_id string · path
required
Body · CreateCommentapplication/json
body string · min length: 1 · max length: 4000
required
object_id string · max length: 64
parent_id string · max length: 64
nx number
ny number
propertyName anything
Responses
200Successful Response
POST /papers/example/comments
1curl -X POST "http://localhost:8000/papers/example/comments" \
2 -H "Content-Type: application/json" \
3 -d '{"body":"string","object_id":"string","parent_id":"string","nx":1.5,"ny":1.5}'
1fetch("http://localhost:8000/papers/example/comments", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "body": "string",
6 "object_id": "string",
7 "parent_id": "string",
8 "nx": 1.5,
9 "ny": 1.5
10}),
11})
12 .then((res) => res.json())
13 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/papers/example/comments",
5 json={"body":"string","object_id":"string","parent_id":"string","nx":1.5,"ny":1.5},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /papers/:document_id/presence undocumented

/papers/:document_id/presence

PUT /papers/:document_id/presence — update cursor position.

Handled by api_update_presence
Parameters
document_id string · path
required
Responses
200Successful Response
PUT /papers/example/presence
1curl -X PUT "http://localhost:8000/papers/example/presence"
1fetch("http://localhost:8000/papers/example/presence", { method: "PUT" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.put("http://localhost:8000/papers/example/presence")
4print(response.json())
200 Example Response
No Body
PATCH /calls/:id/participants/:member_mrn

Update participant role

Handled by api_update_participant
Parameters
id string · path
required
member_mrn string · path
required
Body · UpdateParticipantapplication/json
role
status
can_speak
propertyName anything
Responses
200Successful Response
PATCH /calls/example/participants/example
1curl -X PATCH "http://localhost:8000/calls/example/participants/example" \
2 -H "Content-Type: application/json" \
3 -d '{"role":null,"status":null,"can_speak":null}'
1fetch("http://localhost:8000/calls/example/participants/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "role": null,
6 "status": null,
7 "can_speak": null
8}),
9})
10 .then((res) => res.json())
11 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/calls/example/participants/example",
5 json={"role":null,"status":null,"can_speak":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /chats/:id/participants/:member_mrn

Update participant role

PATCH /chats/:id/participants/:member_mrn — change a participant's role.

Handled by api_update_participant
Parameters
id string · path
required
member_mrn string · path
required
Body · UpdateParticipantapplication/json
role
status
can_speak
propertyName anything
Responses
200Successful Response
PATCH /chats/example/participants/example
1curl -X PATCH "http://localhost:8000/chats/example/participants/example" \
2 -H "Content-Type: application/json" \
3 -d '{"role":null,"status":null,"can_speak":null}'
1fetch("http://localhost:8000/chats/example/participants/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "role": null,
6 "status": null,
7 "can_speak": null
8}),
9})
10 .then((res) => res.json())
11 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/chats/example/participants/example",
5 json={"role":null,"status":null,"can_speak":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /calls/:id/participants

Invite participants

Handled by api_invite_participants
Parameters
id string · path
required
Body · InviteParticipantsapplication/json
members array
required
propertyName anything
Responses
200Successful Response
POST /calls/example/participants
1curl -X POST "http://localhost:8000/calls/example/participants" \
2 -H "Content-Type: application/json" \
3 -d '{"members":["string"]}'
1fetch("http://localhost:8000/calls/example/participants", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "members": [
6 "string"
7 ]
8}),
9})
10 .then((res) => res.json())
11 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/calls/example/participants",
5 json={"members":["string"]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /chats/:id/participants

Add participants

POST /chats/:id/participants — add participants to a group.

Handled by api_add_participants
Parameters
id string · path
required
Body · AddParticipantsapplication/json
members array
required
history
history_days integer · min: 1 · max: 3650
share_history
propertyName anything
Responses
200Successful Response
POST /chats/example/participants
1curl -X POST "http://localhost:8000/chats/example/participants" \
2 -H "Content-Type: application/json" \
3 -d '{"members":["string"],"history":null,"history_days":1,"share_history":null}'
1fetch("http://localhost:8000/chats/example/participants", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "members": [
6 "string"
7 ],
8 "history": null,
9 "history_days": 1,
10 "share_history": null
11}),
12})
13 .then((res) => res.json())
14 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/chats/example/participants",
5 json={"members":["string"],"history":null,"history_days":1,"share_history":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
DELETE /payment-methods/:pm_id undocumented

/payment-methods/:pm_id

DELETE /payment-methods/:pm_id — Remove a payment method.

Handled by api_remove_payment_method
Parameters
pm_id string · path
required
Responses
200Successful Response
DELETE /payment-methods/example
1curl -X DELETE "http://localhost:8000/payment-methods/example"
1fetch("http://localhost:8000/payment-methods/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/payment-methods/example")
4print(response.json())
200 Example Response
No Body
PUT /payment-methods/:pm_id undocumented

/payment-methods/:pm_id

PUT /payment-methods/:pm_id — Set default payment method.

Handled by api_set_default_method
Parameters
pm_id string · path
required
Responses
200Successful Response
PUT /payment-methods/example
1curl -X PUT "http://localhost:8000/payment-methods/example"
1fetch("http://localhost:8000/payment-methods/example", { method: "PUT" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.put("http://localhost:8000/payment-methods/example")
4print(response.json())
200 Example Response
No Body
PATCH /finance/payments/:payment_id

Apply allocations

Apply new allocations to an unallocated (or partially-allocated) payment.

Handled by api_patch_payment
Parameters
payment_id string · path
required
Body · ApplyAllocationsapplication/json
allocations array
required
propertyName anything
Responses
200Successful Response
PATCH /finance/payments/example
1curl -X PATCH "http://localhost:8000/finance/payments/example" \
2 -H "Content-Type: application/json" \
3 -d '{"allocations":[{"entry_id":"string","amount":1.5,"entry_amount":1.5}]}'
1fetch("http://localhost:8000/finance/payments/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "allocations": [
6 {
7 "entry_id": "string",
8 "amount": 1.5,
9 "entry_amount": 1.5
10 }
11 ]
12}),
13})
14 .then((res) => res.json())
15 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/finance/payments/example",
5 json={"allocations":[{"entry_id":"string","amount":1.5,"entry_amount":1.5}]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /finance/payments

Record a payment

Handled by api_create_payment
Body · CreatePaymentapplication/json
direction
required
amount number
required
method
required
paid_at string · min length: 10
required
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
Responses
200Successful Response
POST /finance/payments
1curl -X POST "http://localhost:8000/finance/payments" \
2 -H "Content-Type: application/json" \
3 -d '{"direction":null,"amount":1.5,"method":null,"paid_at":"string","bank_account_id":"string","allocations":[{"entry_id":"string","amount":1.5,"entry_amount":1.5}],"allocate_entry_id":"string","allocate_entry_amount":1.5,"allow_overpayment":null,"contact_mrn":"string","company_mrn":"string","currency":null,"exchange_rate":1.5,"reference":"string","memo":"string","idempotency_key":"string"}'
1fetch("http://localhost:8000/finance/payments", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "direction": null,
6 "amount": 1.5,
7 "method": null,
8 "paid_at": "string",
9 "bank_account_id": "string",
10 "allocations": [
11 {
12 "entry_id": "string",
13 "amount": 1.5,
14 "entry_amount": 1.5
15 }
16 ],
17 "allocate_entry_id": "string",
18 "allocate_entry_amount": 1.5,
19 "allow_overpayment": null,
20 "contact_mrn": "string",
21 "company_mrn": "string",
22 "currency": null,
23 "exchange_rate": 1.5,
24 "reference": "string",
25 "memo": "string",
26 "idempotency_key": "string"
27}),
28})
29 .then((res) => res.json())
30 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/finance/payments",
5 json={"direction":null,"amount":1.5,"method":null,"paid_at":"string","bank_account_id":"string","allocations":[{"entry_id":"string","amount":1.5,"entry_amount":1.5}],"allocate_entry_id":"string","allocate_entry_amount":1.5,"allow_overpayment":null,"contact_mrn":"string","company_mrn":"string","currency":null,"exchange_rate":1.5,"reference":"string","memo":"string","idempotency_key":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /finance/payments/:payment_id/reversals

Reverse a payment

Handled by api_reverse_payment
Parameters
payment_id string · path
required
Body · CreateReversalapplication/json
reason string · min length: 1 · max length: 500
required
propertyName anything
Responses
200Successful Response
POST /finance/payments/example/reversals
1curl -X POST "http://localhost:8000/finance/payments/example/reversals" \
2 -H "Content-Type: application/json" \
3 -d '{"reason":"string"}'
1fetch("http://localhost:8000/finance/payments/example/reversals", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "reason": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/finance/payments/example/reversals",
5 json={"reason":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /finance/fiscal-periods/:period_id

Update/close a period

Handled by api_patch_fiscal_period
Parameters
period_id string · path
required
Body · UpdateFiscalPeriodapplication/json
name string · min length: 1 · max length: 50
start string · min length: 10
end string · min length: 10
status
propertyName anything
Responses
200Successful Response
PATCH /finance/fiscal-periods/example
1curl -X PATCH "http://localhost:8000/finance/fiscal-periods/example" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","start":"string","end":"string","status":null}'
1fetch("http://localhost:8000/finance/fiscal-periods/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "start": "string",
7 "end": "string",
8 "status": null
9}),
10})
11 .then((res) => res.json())
12 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/finance/fiscal-periods/example",
5 json={"name":"string","start":"string","end":"string","status":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /finance/fiscal-periods

Create a fiscal period

Handled by api_create_fiscal_period
Body · FiscalPeriodapplication/json
name string · min length: 1 · max length: 50
required
start string · min length: 10
required
end string · min length: 10
required
status
propertyName anything
Responses
200Successful Response
POST /finance/fiscal-periods
1curl -X POST "http://localhost:8000/finance/fiscal-periods" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","start":"string","end":"string","status":null}'
1fetch("http://localhost:8000/finance/fiscal-periods", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "start": "string",
7 "end": "string",
8 "status": null
9}),
10})
11 .then((res) => res.json())
12 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/finance/fiscal-periods",
5 json={"name":"string","start":"string","end":"string","status":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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.

Handled by api_create_revaluation
Parameters
period_id string · path
required
Body · CreateRevaluationapplication/json
as_of string · min length: 10
required
rates
required
propertyName anything
Responses
200Successful Response
POST /finance/fiscal-periods/example/revaluations
1curl -X POST "http://localhost:8000/finance/fiscal-periods/example/revaluations" \
2 -H "Content-Type: application/json" \
3 -d '{"as_of":"string","rates":null}'
1fetch("http://localhost:8000/finance/fiscal-periods/example/revaluations", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "as_of": "string",
6 "rates": null
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/finance/fiscal-periods/example/revaluations",
5 json={"as_of":"string","rates":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /folders/:folder_id/permissions

Update folder permission

Handled by api_update_folder_permission
Parameters
folder_id string · path
required
Body · UpdateFolderPermissionapplication/json
member_mrn string · min length: 1
required
role
required
propertyName anything
Responses
200Successful Response
PATCH /folders/example/permissions
1curl -X PATCH "http://localhost:8000/folders/example/permissions" \
2 -H "Content-Type: application/json" \
3 -d '{"member_mrn":"string","role":null}'
1fetch("http://localhost:8000/folders/example/permissions", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "member_mrn": "string",
6 "role": null
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/folders/example/permissions",
5 json={"member_mrn":"string","role":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /files/:file_id/permissions

Update file permission

Handled by api_update_file_permission
Parameters
file_id string · path
required
Body · UpdateFilePermissionapplication/json
member_mrn string · min length: 1
required
role
required
propertyName anything
Responses
200Successful Response
PATCH /files/example/permissions
1curl -X PATCH "http://localhost:8000/files/example/permissions" \
2 -H "Content-Type: application/json" \
3 -d '{"member_mrn":"string","role":null}'
1fetch("http://localhost:8000/files/example/permissions", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "member_mrn": "string",
6 "role": null
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/files/example/permissions",
5 json={"member_mrn":"string","role":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /folders/:folder_id/permissions

Grant folder permissions

Handled by api_grant_folder_permissions
Parameters
folder_id string · path
required
Body · GrantFolderPermissionsapplication/json
members array
required
propertyName anything
Responses
200Successful Response
POST /folders/example/permissions
1curl -X POST "http://localhost:8000/folders/example/permissions" \
2 -H "Content-Type: application/json" \
3 -d '{"members":[{"mrn":"string","role":null}]}'
1fetch("http://localhost:8000/folders/example/permissions", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "members": [
6 {
7 "mrn": "string",
8 "role": null
9 }
10 ]
11}),
12})
13 .then((res) => res.json())
14 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/folders/example/permissions",
5 json={"members":[{"mrn":"string","role":null}]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /files/:file_id/permissions

Grant file permissions

Handled by api_grant_file_permissions
Parameters
file_id string · path
required
Body · GrantFilePermissionsapplication/json
members array
required
propertyName anything
Responses
200Successful Response
POST /files/example/permissions
1curl -X POST "http://localhost:8000/files/example/permissions" \
2 -H "Content-Type: application/json" \
3 -d '{"members":[{"mrn":"string","role":null}]}'
1fetch("http://localhost:8000/files/example/permissions", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "members": [
6 {
7 "mrn": "string",
8 "role": null
9 }
10 ]
11}),
12})
13 .then((res) => res.json())
14 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/files/example/permissions",
5 json={"members":[{"mrn":"string","role":null}]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
DELETE /pipelines/:pipeline_id undocumented

/pipelines/:pipeline_id

Handled by api_delete_pipeline
Parameters
pipeline_id string · path
required
Responses
200Successful Response
DELETE /pipelines/example
1curl -X DELETE "http://localhost:8000/pipelines/example"
1fetch("http://localhost:8000/pipelines/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/pipelines/example")
4print(response.json())
200 Example Response
No Body
DELETE /pipelines/:pipeline_id/stages/:stage_id undocumented

/pipelines/:pipeline_id/stages/:stage_id

Handled by api_delete_stage
Parameters
pipeline_id string · path
required
stage_id string · path
required
Responses
200Successful Response
DELETE /pipelines/example/stages/example
1curl -X DELETE "http://localhost:8000/pipelines/example/stages/example"
1fetch("http://localhost:8000/pipelines/example/stages/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/pipelines/example/stages/example")
4print(response.json())
200 Example Response
No Body
GET /pipelines undocumented

/pipelines

Handled by api_list_pipelines
Responses
200Successful Response
GET /pipelines
1curl "http://localhost:8000/pipelines"
1fetch("http://localhost:8000/pipelines")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/pipelines")
4print(response.json())
200 Example Response
No Body
GET /pipelines/:pipeline_id undocumented

/pipelines/:pipeline_id

Handled by api_get_pipeline
Parameters
pipeline_id string · path
required
Responses
200Successful Response
GET /pipelines/example
1curl "http://localhost:8000/pipelines/example"
1fetch("http://localhost:8000/pipelines/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/pipelines/example")
4print(response.json())
200 Example Response
No Body
GET /pipelines/:pipeline_id/stages undocumented

/pipelines/:pipeline_id/stages

Handled by api_list_stages
Parameters
pipeline_id string · path
required
Responses
200Successful Response
GET /pipelines/example/stages
1curl "http://localhost:8000/pipelines/example/stages"
1fetch("http://localhost:8000/pipelines/example/stages")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/pipelines/example/stages")
4print(response.json())
200 Example Response
No Body
POST /pipelines

Create a pipeline

Handled by api_create_pipeline
Body · CreatePipelineapplication/json
name string · min length: 1 · max length: 100
required
description string · max length: 1000
is_default
propertyName anything
Responses
200Successful Response
POST /pipelines
1curl -X POST "http://localhost:8000/pipelines" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","description":"string","is_default":null}'
1fetch("http://localhost:8000/pipelines", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "description": "string",
7 "is_default": null
8}),
9})
10 .then((res) => res.json())
11 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/pipelines",
5 json={"name":"string","description":"string","is_default":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /pipelines/:pipeline_id/stages

Add a stage to a pipeline

Handled by api_create_stage
Parameters
pipeline_id string · path
required
Body · CreateStageapplication/json
name string · min length: 1 · max length: 100
required
type
required
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
Responses
200Successful Response
POST /pipelines/example/stages
1curl -X POST "http://localhost:8000/pipelines/example/stages" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","type":null,"key":"string","position":1,"criteria":[{"label":"string","key":"string","weight":1,"competency_mrn":"string","description":"string"}],"questions":[{"text":"string","category":"string"}],"default_interviewers":["string"],"required_evaluations":1,"sla_days":1,"duration_minutes":1}'
1fetch("http://localhost:8000/pipelines/example/stages", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "type": null,
7 "key": "string",
8 "position": 1,
9 "criteria": [
10 {
11 "label": "string",
12 "key": "string",
13 "weight": 1,
14 "competency_mrn": "string",
15 "description": "string"
16 }
17 ],
18 "questions": [
19 {
20 "text": "string",
21 "category": "string"
22 }
23 ],
24 "default_interviewers": [
25 "string"
26 ],
27 "required_evaluations": 1,
28 "sla_days": 1,
29 "duration_minutes": 1
30}),
31})
32 .then((res) => res.json())
33 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/pipelines/example/stages",
5 json={"name":"string","type":null,"key":"string","position":1,"criteria":[{"label":"string","key":"string","weight":1,"competency_mrn":"string","description":"string"}],"questions":[{"text":"string","category":"string"}],"default_interviewers":["string"],"required_evaluations":1,"sla_days":1,"duration_minutes":1},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /pipelines/:pipeline_id

Update a pipeline

Handled by api_update_pipeline
Parameters
pipeline_id string · path
required
Body · UpdatePipelineapplication/json
name string · min length: 1 · max length: 100
description string · max length: 1000
is_default
status
propertyName anything
Responses
200Successful Response
PUT /pipelines/example
1curl -X PUT "http://localhost:8000/pipelines/example" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","description":"string","is_default":null,"status":null}'
1fetch("http://localhost:8000/pipelines/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "description": "string",
7 "is_default": null,
8 "status": null
9}),
10})
11 .then((res) => res.json())
12 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/pipelines/example",
5 json={"name":"string","description":"string","is_default":null,"status":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /pipelines/:pipeline_id/stages/:stage_id

Update a stage

Handled by api_update_stage
Parameters
pipeline_id string · path
required
stage_id string · path
required
Body · UpdateStageapplication/json
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
Responses
200Successful Response
PUT /pipelines/example/stages/example
1curl -X PUT "http://localhost:8000/pipelines/example/stages/example" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","type":null,"key":"string","criteria":[{"label":"string","key":"string","weight":1,"competency_mrn":"string","description":"string"}],"questions":[{"text":"string","category":"string"}],"default_interviewers":["string"],"required_evaluations":1,"sla_days":1,"duration_minutes":1}'
1fetch("http://localhost:8000/pipelines/example/stages/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "type": null,
7 "key": "string",
8 "criteria": [
9 {
10 "label": "string",
11 "key": "string",
12 "weight": 1,
13 "competency_mrn": "string",
14 "description": "string"
15 }
16 ],
17 "questions": [
18 {
19 "text": "string",
20 "category": "string"
21 }
22 ],
23 "default_interviewers": [
24 "string"
25 ],
26 "required_evaluations": 1,
27 "sla_days": 1,
28 "duration_minutes": 1
29}),
30})
31 .then((res) => res.json())
32 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/pipelines/example/stages/example",
5 json={"name":"string","type":null,"key":"string","criteria":[{"label":"string","key":"string","weight":1,"competency_mrn":"string","description":"string"}],"questions":[{"text":"string","category":"string"}],"default_interviewers":["string"],"required_evaluations":1,"sla_days":1,"duration_minutes":1},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
GET /plan undocumented

/plan

GET /plan: current plan, price book, currency and billing interval.

Handled by api_get_plan
Responses
200Successful Response
GET /plan
1curl "http://localhost:8000/plan"
1fetch("http://localhost:8000/plan")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/plan")
4print(response.json())
200 Example Response
No Body
POST /finance/quotes/:entry_id/links

Share a quote with a customer

Handled by api_create_quote_link
Parameters
entry_id string · path
required
Body · CreatePortalLinkapplication/json
recipient_email string · max length: 320
propertyName anything
Responses
200Successful Response
POST /finance/quotes/example/links
1curl -X POST "http://localhost:8000/finance/quotes/example/links" \
2 -H "Content-Type: application/json" \
3 -d '{"recipient_email":"string"}'
1fetch("http://localhost:8000/finance/quotes/example/links", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "recipient_email": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/finance/quotes/example/links",
5 json={"recipient_email":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /finance/invoices/:entry_id/links

Share an invoice with a customer

Handled by api_create_invoice_link
Parameters
entry_id string · path
required
Body · CreatePortalLinkapplication/json
recipient_email string · max length: 320
propertyName anything
Responses
200Successful Response
POST /finance/invoices/example/links
1curl -X POST "http://localhost:8000/finance/invoices/example/links" \
2 -H "Content-Type: application/json" \
3 -d '{"recipient_email":"string"}'
1fetch("http://localhost:8000/finance/invoices/example/links", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "recipient_email": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/finance/invoices/example/links",
5 json={"recipient_email":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /finance/credit-notes/:entry_id/links

Share a credit note with a customer

Handled by api_create_credit_note_link
Parameters
entry_id string · path
required
Body · CreatePortalLinkapplication/json
recipient_email string · max length: 320
propertyName anything
Responses
200Successful Response
POST /finance/credit-notes/example/links
1curl -X POST "http://localhost:8000/finance/credit-notes/example/links" \
2 -H "Content-Type: application/json" \
3 -d '{"recipient_email":"string"}'
1fetch("http://localhost:8000/finance/credit-notes/example/links", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "recipient_email": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/finance/credit-notes/example/links",
5 json={"recipient_email":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /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.

Handled by api_put_payment_credentials
Parameters
provider string · path
required
Body · UpdatePaymentCredentialsapplication/json
secret_key string · min length: 8 · max length: 200
required
public_key string · max length: 200
enabled
propertyName anything
Responses
200Successful Response
PUT /finance/payment-credentials/example
1curl -X PUT "http://localhost:8000/finance/payment-credentials/example" \
2 -H "Content-Type: application/json" \
3 -d '{"secret_key":"string","public_key":"string","enabled":null}'
1fetch("http://localhost:8000/finance/payment-credentials/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "secret_key": "string",
6 "public_key": "string",
7 "enabled": null
8}),
9})
10 .then((res) => res.json())
11 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/finance/payment-credentials/example",
5 json={"secret_key":"string","public_key":"string","enabled":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
GET /preferences undocumented

/preferences

Handled by get_preferences
Responses
200Successful Response
GET /preferences
1curl "http://localhost:8000/preferences"
1fetch("http://localhost:8000/preferences")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/preferences")
4print(response.json())
200 Example Response
No Body
PUT /preferences undocumented

/preferences

Handled by update_preferences
Responses
200Successful Response
PUT /preferences
1curl -X PUT "http://localhost:8000/preferences"
1fetch("http://localhost:8000/preferences", { method: "PUT" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.put("http://localhost:8000/preferences")
4print(response.json())
200 Example Response
No Body
DELETE /presignations/:id undocumented

/presignations/:id

DELETE /presignations/:id — abandon a multipart upload so no orphaned parts linger (R2 bills incomplete parts until aborted).

Handled by abort_multipart
Parameters
id string · path
required
Responses
200Successful Response
DELETE /presignations/example
1curl -X DELETE "http://localhost:8000/presignations/example"
1fetch("http://localhost:8000/presignations/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/presignations/example")
4print(response.json())
200 Example Response
No Body
POST /presignations undocumented

/presignations

POST /presignations — generate a presigned R2 PUT URL. Body: {app, filename, content_type, size_bytes, context: {...}}

Handled by presign
Responses
200Successful Response
POST /presignations
1curl -X POST "http://localhost:8000/presignations"
1fetch("http://localhost:8000/presignations", { method: "POST" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.post("http://localhost:8000/presignations")
4print(response.json())
200 Example Response
No Body
POST /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.

Handled by confirm
Parameters
id string · path
required
Responses
200Successful Response
POST /presignations/example/confirmations
1curl -X POST "http://localhost:8000/presignations/example/confirmations"
1fetch("http://localhost:8000/presignations/example/confirmations", { method: "POST" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.post("http://localhost:8000/presignations/example/confirmations")
4print(response.json())
200 Example Response
No Body
POST /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.

Handled by complete_multipart
Parameters
id string · path
required
Responses
200Successful Response
POST /presignations/example/completions
1curl -X POST "http://localhost:8000/presignations/example/completions"
1fetch("http://localhost:8000/presignations/example/completions", { method: "POST" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.post("http://localhost:8000/presignations/example/completions")
4print(response.json())
200 Example Response
No Body
PUT /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.

Handled by set_my_locale
Body · SetLocaleapplication/json
locale
required
propertyName anything
Responses
200Successful Response
PUT /me/locale
1curl -X PUT "http://localhost:8000/me/locale" \
2 -H "Content-Type: application/json" \
3 -d '{"locale":null}'
1fetch("http://localhost:8000/me/locale", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "locale": null
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/me/locale",
5 json={"locale":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /profiles/:member_id

Update profile

Update own profile (name, job title).

Handled by update_profile
Parameters
member_id string · path
required
Body · UpdateProfileapplication/json
full_name string · min length: 1 · max length: 200
job_title string · max length: 200
propertyName anything
Responses
200Successful Response
PUT /profiles/example
1curl -X PUT "http://localhost:8000/profiles/example" \
2 -H "Content-Type: application/json" \
3 -d '{"full_name":"string","job_title":"string"}'
1fetch("http://localhost:8000/profiles/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "full_name": "string",
6 "job_title": "string"
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/profiles/example",
5 json={"full_name":"string","job_title":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /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.

Handled by update_contact
Parameters
member_id string · path
required
Body · UpdateContactapplication/json
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
Responses
200Successful Response
PUT /profiles/example/contact
1curl -X PUT "http://localhost:8000/profiles/example/contact" \
2 -H "Content-Type: application/json" \
3 -d '{"phone_number":"string","street":"string","city":"string","state":"string","postal_code":"string","country":"string"}'
1fetch("http://localhost:8000/profiles/example/contact", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "phone_number": "string",
6 "street": "string",
7 "city": "string",
8 "state": "string",
9 "postal_code": "string",
10 "country": "string"
11}),
12})
13 .then((res) => res.json())
14 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/profiles/example/contact",
5 json={"phone_number":"string","street":"string","city":"string","state":"string","postal_code":"string","country":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /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.

Handled by change_password
Parameters
member_id string · path
required
Body · ChangePasswordapplication/json
new_password string · min length: 8
required
current_password string · min length: 1
propertyName anything
Responses
200Successful Response
PUT /passwords/example
1curl -X PUT "http://localhost:8000/passwords/example" \
2 -H "Content-Type: application/json" \
3 -d '{"new_password":"string","current_password":"string"}'
1fetch("http://localhost:8000/passwords/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "new_password": "string",
6 "current_password": "string"
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/passwords/example",
5 json={"new_password":"string","current_password":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /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.

Handled by api_update_worker_fields
Parameters
worker_id string · path
required
Body · UpdateWorkerCustomFieldsapplication/json
values array
required
propertyName anything
Responses
200Successful Response
PATCH /workers/example/fields
1curl -X PATCH "http://localhost:8000/workers/example/fields" \
2 -H "Content-Type: application/json" \
3 -d '{"values":[{"field_id":"string","value":null}]}'
1fetch("http://localhost:8000/workers/example/fields", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "values": [
6 {
7 "field_id": "string",
8 "value": null
9 }
10 ]
11}),
12})
13 .then((res) => res.json())
14 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/workers/example/fields",
5 json={"values":[{"field_id":"string","value":null}]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /workers/fields

Create a custom profile field

Handled by api_create_field_definition
Body · CreateFieldDefinitionapplication/json
label string · min length: 1 · max length: 100
required
type
required
section string · max length: 100
options array
required
sensitive
help_text string · max length: 300
position integer · min: 0 · max: 10000
propertyName anything
Responses
200Successful Response
POST /workers/fields
1curl -X POST "http://localhost:8000/workers/fields" \
2 -H "Content-Type: application/json" \
3 -d '{"label":"string","type":null,"section":"string","options":["string"],"required":null,"sensitive":null,"help_text":"string","position":1}'
1fetch("http://localhost:8000/workers/fields", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "label": "string",
6 "type": null,
7 "section": "string",
8 "options": [
9 "string"
10 ],
11 "required": null,
12 "sensitive": null,
13 "help_text": "string",
14 "position": 1
15}),
16})
17 .then((res) => res.json())
18 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/workers/fields",
5 json={"label":"string","type":null,"section":"string","options":["string"],"required":null,"sensitive":null,"help_text":"string","position":1},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /workers/fields/:field_id

Update a custom profile field

Handled by api_update_field_definition
Parameters
field_id string · path
required
Body · UpdateFieldDefinitionapplication/json
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
Responses
200Successful Response
PUT /workers/fields/example
1curl -X PUT "http://localhost:8000/workers/fields/example" \
2 -H "Content-Type: application/json" \
3 -d '{"label":"string","section":"string","options":["string"],"required":null,"sensitive":null,"help_text":"string","position":1}'
1fetch("http://localhost:8000/workers/fields/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "label": "string",
6 "section": "string",
7 "options": [
8 "string"
9 ],
10 "required": null,
11 "sensitive": null,
12 "help_text": "string",
13 "position": 1
14}),
15})
16 .then((res) => res.json())
17 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/workers/fields/example",
5 json={"label":"string","section":"string","options":["string"],"required":null,"sensitive":null,"help_text":"string","position":1},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
DELETE /ptos/:id undocumented

/ptos/:id

Cancel a PTO (worker) or revoke (manager).

Handled by api_delete_pto
Parameters
id string · path
required
Responses
200Successful Response
DELETE /ptos/example
1curl -X DELETE "http://localhost:8000/ptos/example"
1fetch("http://localhost:8000/ptos/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/ptos/example")
4print(response.json())
200 Example Response
No Body
GET /ptos undocumented

/ptos

Handled by api_list_ptos
Responses
200Successful Response
GET /ptos
1curl "http://localhost:8000/ptos"
1fetch("http://localhost:8000/ptos")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/ptos")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_list_pending_ptos
Responses
200Successful Response
GET /ptos/pending
1curl "http://localhost:8000/ptos/pending"
1fetch("http://localhost:8000/ptos/pending")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/ptos/pending")
4print(response.json())
200 Example Response
No Body
GET /ptos/:id undocumented

/ptos/:id

Handled by api_get_pto
Parameters
id string · path
required
Responses
200Successful Response
GET /ptos/example
1curl "http://localhost:8000/ptos/example"
1fetch("http://localhost:8000/ptos/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/ptos/example")
4print(response.json())
200 Example Response
No Body
PATCH /finance/purchase-credit-notes/:entry_id

Issue/void purchase credit note

Handled by api_patch_purchase_credit_note
Parameters
entry_id string · path
required
Body · UpdatePurchaseCreditNoteStatusapplication/json
status
required
propertyName anything
Responses
200Successful Response
PATCH /finance/purchase-credit-notes/example
1curl -X PATCH "http://localhost:8000/finance/purchase-credit-notes/example" \
2 -H "Content-Type: application/json" \
3 -d '{"status":null}'
1fetch("http://localhost:8000/finance/purchase-credit-notes/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "status": null
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/finance/purchase-credit-notes/example",
5 json={"status":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /finance/purchase-credit-notes

Record a vendor credit note

Handled by api_create_purchase_credit_note
Body · CreatePurchaseCreditNoteapplication/json
date string · min length: 10
required
items array
source_entry_id string · min length: 1
required
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
Responses
200Successful Response
POST /finance/purchase-credit-notes
1curl -X POST "http://localhost:8000/finance/purchase-credit-notes" \
2 -H "Content-Type: application/json" \
3 -d '{"date":"string","items":[{"description":"string","quantity":1.5,"unit_price":1.5,"discount":1.5,"amount":1.5,"account_code":"string","product_mrn":"string","taxes":[{"name":"string","rate":1.5,"amount":1.5,"reverse_charge":null}]}],"source_entry_id":"string","contact_mrn":"string","company_mrn":"string","currency":null,"exchange_rate":1.5,"memo":"string","adjustments":[{"label":"string","type":null,"value":1.5,"amount":1.5,"account_code":"string"}],"dimensions":null,"idempotency_key":"string"}'
1fetch("http://localhost:8000/finance/purchase-credit-notes", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "date": "string",
6 "items": [
7 {
8 "description": "string",
9 "quantity": 1.5,
10 "unit_price": 1.5,
11 "discount": 1.5,
12 "amount": 1.5,
13 "account_code": "string",
14 "product_mrn": "string",
15 "taxes": [
16 {
17 "name": "string",
18 "rate": 1.5,
19 "amount": 1.5,
20 "reverse_charge": null
21 }
22 ]
23 }
24 ],
25 "source_entry_id": "string",
26 "contact_mrn": "string",
27 "company_mrn": "string",
28 "currency": null,
29 "exchange_rate": 1.5,
30 "memo": "string",
31 "adjustments": [
32 {
33 "label": "string",
34 "type": null,
35 "value": 1.5,
36 "amount": 1.5,
37 "account_code": "string"
38 }
39 ],
40 "dimensions": null,
41 "idempotency_key": "string"
42}),
43})
44 .then((res) => res.json())
45 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/finance/purchase-credit-notes",
5 json={"date":"string","items":[{"description":"string","quantity":1.5,"unit_price":1.5,"discount":1.5,"amount":1.5,"account_code":"string","product_mrn":"string","taxes":[{"name":"string","rate":1.5,"amount":1.5,"reverse_charge":null}]}],"source_entry_id":"string","contact_mrn":"string","company_mrn":"string","currency":null,"exchange_rate":1.5,"memo":"string","adjustments":[{"label":"string","type":null,"value":1.5,"amount":1.5,"account_code":"string"}],"dimensions":null,"idempotency_key":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /finance/purchase-credit-notes/:entry_id/allocations

Set vendor credit against a bill

Handled by api_create_purchase_credit_note_allocation
Parameters
entry_id string · path
required
Body · CreatePurchaseCreditNoteAllocationapplication/json
entry_id string · min length: 1
required
amount number
required
entry_amount number
propertyName anything
Responses
200Successful Response
POST /finance/purchase-credit-notes/example/allocations
1curl -X POST "http://localhost:8000/finance/purchase-credit-notes/example/allocations" \
2 -H "Content-Type: application/json" \
3 -d '{"entry_id":"string","amount":1.5,"entry_amount":1.5}'
1fetch("http://localhost:8000/finance/purchase-credit-notes/example/allocations", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "entry_id": "string",
6 "amount": 1.5,
7 "entry_amount": 1.5
8}),
9})
10 .then((res) => res.json())
11 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/finance/purchase-credit-notes/example/allocations",
5 json={"entry_id":"string","amount":1.5,"entry_amount":1.5},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /finance/purchase-credit-notes/:entry_id

Update a draft purchase credit note

Handled by api_update_purchase_credit_note
Parameters
entry_id string · path
required
Body · UpdatePurchaseCreditNoteapplication/json
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
Responses
200Successful Response
PUT /finance/purchase-credit-notes/example
1curl -X PUT "http://localhost:8000/finance/purchase-credit-notes/example" \
2 -H "Content-Type: application/json" \
3 -d '{"date":"string","items":[{"description":"string","quantity":1.5,"unit_price":1.5,"discount":1.5,"amount":1.5,"account_code":"string","product_mrn":"string","taxes":[{"name":"string","rate":1.5,"amount":1.5,"reverse_charge":null}]}],"contact_mrn":"string","company_mrn":"string","currency":null,"exchange_rate":1.5,"memo":"string","adjustments":[{"label":"string","type":null,"value":1.5,"amount":1.5,"account_code":"string"}],"dimensions":null}'
1fetch("http://localhost:8000/finance/purchase-credit-notes/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "date": "string",
6 "items": [
7 {
8 "description": "string",
9 "quantity": 1.5,
10 "unit_price": 1.5,
11 "discount": 1.5,
12 "amount": 1.5,
13 "account_code": "string",
14 "product_mrn": "string",
15 "taxes": [
16 {
17 "name": "string",
18 "rate": 1.5,
19 "amount": 1.5,
20 "reverse_charge": null
21 }
22 ]
23 }
24 ],
25 "contact_mrn": "string",
26 "company_mrn": "string",
27 "currency": null,
28 "exchange_rate": 1.5,
29 "memo": "string",
30 "adjustments": [
31 {
32 "label": "string",
33 "type": null,
34 "value": 1.5,
35 "amount": 1.5,
36 "account_code": "string"
37 }
38 ],
39 "dimensions": null
40}),
41})
42 .then((res) => res.json())
43 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/finance/purchase-credit-notes/example",
5 json={"date":"string","items":[{"description":"string","quantity":1.5,"unit_price":1.5,"discount":1.5,"amount":1.5,"account_code":"string","product_mrn":"string","taxes":[{"name":"string","rate":1.5,"amount":1.5,"reverse_charge":null}]}],"contact_mrn":"string","company_mrn":"string","currency":null,"exchange_rate":1.5,"memo":"string","adjustments":[{"label":"string","type":null,"value":1.5,"amount":1.5,"account_code":"string"}],"dimensions":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /finance/purchase-orders/:entry_id

Transition a PO

Handled by api_patch_purchase_order
Parameters
entry_id string · path
required
Body · UpdatePurchaseOrderStatusapplication/json
status
required
propertyName anything
Responses
200Successful Response
PATCH /finance/purchase-orders/example
1curl -X PATCH "http://localhost:8000/finance/purchase-orders/example" \
2 -H "Content-Type: application/json" \
3 -d '{"status":null}'
1fetch("http://localhost:8000/finance/purchase-orders/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "status": null
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/finance/purchase-orders/example",
5 json={"status":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /finance/purchase-orders

Create a purchase order

Handled by api_create_purchase_order
Body · CreatePurchaseOrderapplication/json
date string · min length: 10
required
items array
company_mrn string
contact_mrn string
currency
required
exchange_rate number
memo string · max length: 5000
tags array
adjustments array
idempotency_key string · max length: 100
propertyName anything
Responses
200Successful Response
POST /finance/purchase-orders
1curl -X POST "http://localhost:8000/finance/purchase-orders" \
2 -H "Content-Type: application/json" \
3 -d '{"date":"string","items":[{"description":"string","quantity":1.5,"unit_price":1.5,"discount":1.5,"amount":1.5,"account_code":"string","product_mrn":"string","taxes":[{"name":"string","rate":1.5,"amount":1.5,"reverse_charge":null}]}],"company_mrn":"string","contact_mrn":"string","currency":null,"exchange_rate":1.5,"memo":"string","tags":["string"],"adjustments":[{"label":"string","type":null,"value":1.5,"amount":1.5,"account_code":"string"}],"idempotency_key":"string"}'
1fetch("http://localhost:8000/finance/purchase-orders", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "date": "string",
6 "items": [
7 {
8 "description": "string",
9 "quantity": 1.5,
10 "unit_price": 1.5,
11 "discount": 1.5,
12 "amount": 1.5,
13 "account_code": "string",
14 "product_mrn": "string",
15 "taxes": [
16 {
17 "name": "string",
18 "rate": 1.5,
19 "amount": 1.5,
20 "reverse_charge": null
21 }
22 ]
23 }
24 ],
25 "company_mrn": "string",
26 "contact_mrn": "string",
27 "currency": null,
28 "exchange_rate": 1.5,
29 "memo": "string",
30 "tags": [
31 "string"
32 ],
33 "adjustments": [
34 {
35 "label": "string",
36 "type": null,
37 "value": 1.5,
38 "amount": 1.5,
39 "account_code": "string"
40 }
41 ],
42 "idempotency_key": "string"
43}),
44})
45 .then((res) => res.json())
46 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/finance/purchase-orders",
5 json={"date":"string","items":[{"description":"string","quantity":1.5,"unit_price":1.5,"discount":1.5,"amount":1.5,"account_code":"string","product_mrn":"string","taxes":[{"name":"string","rate":1.5,"amount":1.5,"reverse_charge":null}]}],"company_mrn":"string","contact_mrn":"string","currency":null,"exchange_rate":1.5,"memo":"string","tags":["string"],"adjustments":[{"label":"string","type":null,"value":1.5,"amount":1.5,"account_code":"string"}],"idempotency_key":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /finance/purchase-orders/:entry_id/receipts

Record a receipt

Record a receipt against a PO — auto-creates a draft bill with the selected lines.

Handled by api_create_receipt
Parameters
entry_id string · path
required
Body · CreateReceiptapplication/json
date string · min length: 10
required
lines array
required
memo string · max length: 2000
propertyName anything
Responses
200Successful Response
POST /finance/purchase-orders/example/receipts
1curl -X POST "http://localhost:8000/finance/purchase-orders/example/receipts" \
2 -H "Content-Type: application/json" \
3 -d '{"date":"string","lines":[{"item_index":1,"quantity":1.5}],"memo":"string"}'
1fetch("http://localhost:8000/finance/purchase-orders/example/receipts", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "date": "string",
6 "lines": [
7 {
8 "item_index": 1,
9 "quantity": 1.5
10 }
11 ],
12 "memo": "string"
13}),
14})
15 .then((res) => res.json())
16 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/finance/purchase-orders/example/receipts",
5 json={"date":"string","lines":[{"item_index":1,"quantity":1.5}],"memo":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /finance/purchase-orders/:entry_id

Update a draft PO

Handled by api_update_purchase_order
Parameters
entry_id string · path
required
Body · UpdatePurchaseOrderapplication/json
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
Responses
200Successful Response
PUT /finance/purchase-orders/example
1curl -X PUT "http://localhost:8000/finance/purchase-orders/example" \
2 -H "Content-Type: application/json" \
3 -d '{"date":"string","items":[{"description":"string","quantity":1.5,"unit_price":1.5,"discount":1.5,"amount":1.5,"account_code":"string","product_mrn":"string","taxes":[{"name":"string","rate":1.5,"amount":1.5,"reverse_charge":null}]}],"company_mrn":"string","contact_mrn":"string","currency":null,"exchange_rate":1.5,"memo":"string","tags":["string"],"adjustments":[{"label":"string","type":null,"value":1.5,"amount":1.5,"account_code":"string"}],"dimensions":null}'
1fetch("http://localhost:8000/finance/purchase-orders/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "date": "string",
6 "items": [
7 {
8 "description": "string",
9 "quantity": 1.5,
10 "unit_price": 1.5,
11 "discount": 1.5,
12 "amount": 1.5,
13 "account_code": "string",
14 "product_mrn": "string",
15 "taxes": [
16 {
17 "name": "string",
18 "rate": 1.5,
19 "amount": 1.5,
20 "reverse_charge": null
21 }
22 ]
23 }
24 ],
25 "company_mrn": "string",
26 "contact_mrn": "string",
27 "currency": null,
28 "exchange_rate": 1.5,
29 "memo": "string",
30 "tags": [
31 "string"
32 ],
33 "adjustments": [
34 {
35 "label": "string",
36 "type": null,
37 "value": 1.5,
38 "amount": 1.5,
39 "account_code": "string"
40 }
41 ],
42 "dimensions": null
43}),
44})
45 .then((res) => res.json())
46 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/finance/purchase-orders/example",
5 json={"date":"string","items":[{"description":"string","quantity":1.5,"unit_price":1.5,"discount":1.5,"amount":1.5,"account_code":"string","product_mrn":"string","taxes":[{"name":"string","rate":1.5,"amount":1.5,"reverse_charge":null}]}],"company_mrn":"string","contact_mrn":"string","currency":null,"exchange_rate":1.5,"memo":"string","tags":["string"],"adjustments":[{"label":"string","type":null,"value":1.5,"amount":1.5,"account_code":"string"}],"dimensions":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
DELETE /push-devices/:id undocumented

/push-devices/:id

DELETE /push-devices/:id: stop notifying this phone.

Handled by api_delete_device
Parameters
id string · path
required
Responses
200Successful Response
DELETE /push-devices/example
1curl -X DELETE "http://localhost:8000/push-devices/example"
1fetch("http://localhost:8000/push-devices/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/push-devices/example")
4print(response.json())
200 Example Response
No Body
DELETE /push-subscriptions/:id undocumented

/push-subscriptions/:id

DELETE /push-subscriptions/:id: stop notifying this browser.

Handled by api_delete_subscription
Parameters
id string · path
required
Responses
200Successful Response
DELETE /push-subscriptions/example
1curl -X DELETE "http://localhost:8000/push-subscriptions/example"
1fetch("http://localhost:8000/push-subscriptions/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/push-subscriptions/example")
4print(response.json())
200 Example Response
No Body
PATCH /finance/quotes/:entry_id

Transition a quote

Handled by api_patch_quote
Parameters
entry_id string · path
required
Body · UpdateQuoteStatusapplication/json
status
required
propertyName anything
Responses
200Successful Response
PATCH /finance/quotes/example
1curl -X PATCH "http://localhost:8000/finance/quotes/example" \
2 -H "Content-Type: application/json" \
3 -d '{"status":null}'
1fetch("http://localhost:8000/finance/quotes/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "status": null
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/finance/quotes/example",
5 json={"status":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /finance/quotes

Create a quote

Handled by api_create_quote
Body · CreateQuoteapplication/json
date string · min length: 10
required
items array
contact_mrn string
company_mrn string
currency
required
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
Responses
200Successful Response
POST /finance/quotes
1curl -X POST "http://localhost:8000/finance/quotes" \
2 -H "Content-Type: application/json" \
3 -d '{"date":"string","items":[{"description":"string","quantity":1.5,"unit_price":1.5,"discount":1.5,"amount":1.5,"account_code":"string","product_mrn":"string","taxes":[{"name":"string","rate":1.5,"amount":1.5,"reverse_charge":null}]}],"contact_mrn":"string","company_mrn":"string","currency":null,"exchange_rate":1.5,"valid_until":"string","memo":"string","tags":["string"],"adjustments":[{"label":"string","type":null,"value":1.5,"amount":1.5,"account_code":"string"}],"idempotency_key":"string"}'
1fetch("http://localhost:8000/finance/quotes", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "date": "string",
6 "items": [
7 {
8 "description": "string",
9 "quantity": 1.5,
10 "unit_price": 1.5,
11 "discount": 1.5,
12 "amount": 1.5,
13 "account_code": "string",
14 "product_mrn": "string",
15 "taxes": [
16 {
17 "name": "string",
18 "rate": 1.5,
19 "amount": 1.5,
20 "reverse_charge": null
21 }
22 ]
23 }
24 ],
25 "contact_mrn": "string",
26 "company_mrn": "string",
27 "currency": null,
28 "exchange_rate": 1.5,
29 "valid_until": "string",
30 "memo": "string",
31 "tags": [
32 "string"
33 ],
34 "adjustments": [
35 {
36 "label": "string",
37 "type": null,
38 "value": 1.5,
39 "amount": 1.5,
40 "account_code": "string"
41 }
42 ],
43 "idempotency_key": "string"
44}),
45})
46 .then((res) => res.json())
47 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/finance/quotes",
5 json={"date":"string","items":[{"description":"string","quantity":1.5,"unit_price":1.5,"discount":1.5,"amount":1.5,"account_code":"string","product_mrn":"string","taxes":[{"name":"string","rate":1.5,"amount":1.5,"reverse_charge":null}]}],"contact_mrn":"string","company_mrn":"string","currency":null,"exchange_rate":1.5,"valid_until":"string","memo":"string","tags":["string"],"adjustments":[{"label":"string","type":null,"value":1.5,"amount":1.5,"account_code":"string"}],"idempotency_key":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /finance/quotes/:entry_id/sends

Email a quote

Handled by api_send_quote
Parameters
entry_id string · path
required
Body · SendQuoteapplication/json
to string · min length: 1 · max length: 500
required
cc string · max length: 500
subject string · max length: 300
message string · max length: 5000
propertyName anything
Responses
200Successful Response
POST /finance/quotes/example/sends
1curl -X POST "http://localhost:8000/finance/quotes/example/sends" \
2 -H "Content-Type: application/json" \
3 -d '{"to":"string","cc":"string","subject":"string","message":"string"}'
1fetch("http://localhost:8000/finance/quotes/example/sends", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "to": "string",
6 "cc": "string",
7 "subject": "string",
8 "message": "string"
9}),
10})
11 .then((res) => res.json())
12 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/finance/quotes/example/sends",
5 json={"to":"string","cc":"string","subject":"string","message":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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.

Handled by api_create_quote_revision
Parameters
entry_id string · path
required
Body · ReviseQuoteapplication/json
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
Responses
200Successful Response
POST /finance/quotes/example/revisions
1curl -X POST "http://localhost:8000/finance/quotes/example/revisions" \
2 -H "Content-Type: application/json" \
3 -d '{"date":"string","items":[{"description":"string","quantity":1.5,"unit_price":1.5,"discount":1.5,"amount":1.5,"account_code":"string","product_mrn":"string","taxes":[{"name":"string","rate":1.5,"amount":1.5,"reverse_charge":null}]}],"contact_mrn":"string","company_mrn":"string","currency":null,"exchange_rate":1.5,"valid_until":"string","memo":"string","tags":["string"],"resend":null,"to":"string"}'
1fetch("http://localhost:8000/finance/quotes/example/revisions", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "date": "string",
6 "items": [
7 {
8 "description": "string",
9 "quantity": 1.5,
10 "unit_price": 1.5,
11 "discount": 1.5,
12 "amount": 1.5,
13 "account_code": "string",
14 "product_mrn": "string",
15 "taxes": [
16 {
17 "name": "string",
18 "rate": 1.5,
19 "amount": 1.5,
20 "reverse_charge": null
21 }
22 ]
23 }
24 ],
25 "contact_mrn": "string",
26 "company_mrn": "string",
27 "currency": null,
28 "exchange_rate": 1.5,
29 "valid_until": "string",
30 "memo": "string",
31 "tags": [
32 "string"
33 ],
34 "resend": null,
35 "to": "string"
36}),
37})
38 .then((res) => res.json())
39 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/finance/quotes/example/revisions",
5 json={"date":"string","items":[{"description":"string","quantity":1.5,"unit_price":1.5,"discount":1.5,"amount":1.5,"account_code":"string","product_mrn":"string","taxes":[{"name":"string","rate":1.5,"amount":1.5,"reverse_charge":null}]}],"contact_mrn":"string","company_mrn":"string","currency":null,"exchange_rate":1.5,"valid_until":"string","memo":"string","tags":["string"],"resend":null,"to":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /finance/quotes/:entry_id

Update a draft quote

Handled by api_update_quote
Parameters
entry_id string · path
required
Body · UpdateQuoteapplication/json
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
Responses
200Successful Response
PUT /finance/quotes/example
1curl -X PUT "http://localhost:8000/finance/quotes/example" \
2 -H "Content-Type: application/json" \
3 -d '{"date":"string","items":[{"description":"string","quantity":1.5,"unit_price":1.5,"discount":1.5,"amount":1.5,"account_code":"string","product_mrn":"string","taxes":[{"name":"string","rate":1.5,"amount":1.5,"reverse_charge":null}]}],"contact_mrn":"string","company_mrn":"string","currency":null,"exchange_rate":1.5,"valid_until":"string","memo":"string","tags":["string"],"adjustments":[{"label":"string","type":null,"value":1.5,"amount":1.5,"account_code":"string"}],"dimensions":null}'
1fetch("http://localhost:8000/finance/quotes/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "date": "string",
6 "items": [
7 {
8 "description": "string",
9 "quantity": 1.5,
10 "unit_price": 1.5,
11 "discount": 1.5,
12 "amount": 1.5,
13 "account_code": "string",
14 "product_mrn": "string",
15 "taxes": [
16 {
17 "name": "string",
18 "rate": 1.5,
19 "amount": 1.5,
20 "reverse_charge": null
21 }
22 ]
23 }
24 ],
25 "contact_mrn": "string",
26 "company_mrn": "string",
27 "currency": null,
28 "exchange_rate": 1.5,
29 "valid_until": "string",
30 "memo": "string",
31 "tags": [
32 "string"
33 ],
34 "adjustments": [
35 {
36 "label": "string",
37 "type": null,
38 "value": 1.5,
39 "amount": 1.5,
40 "account_code": "string"
41 }
42 ],
43 "dimensions": null
44}),
45})
46 .then((res) => res.json())
47 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/finance/quotes/example",
5 json={"date":"string","items":[{"description":"string","quantity":1.5,"unit_price":1.5,"discount":1.5,"amount":1.5,"account_code":"string","product_mrn":"string","taxes":[{"name":"string","rate":1.5,"amount":1.5,"reverse_charge":null}]}],"contact_mrn":"string","company_mrn":"string","currency":null,"exchange_rate":1.5,"valid_until":"string","memo":"string","tags":["string"],"adjustments":[{"label":"string","type":null,"value":1.5,"amount":1.5,"account_code":"string"}],"dimensions":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /chats/:id/messages/:msg_id/reactions

Add a reaction

POST /chats/:id/messages/:msg_id/reactions — add an emoji reaction.

Handled by api_add_reaction
Parameters
id string · path
required
msg_id string · path
required
Body · AddReactionapplication/json
emoji string · min length: 1 · max length: 32
required
propertyName anything
Responses
200Successful Response
POST /chats/example/messages/example/reactions
1curl -X POST "http://localhost:8000/chats/example/messages/example/reactions" \
2 -H "Content-Type: application/json" \
3 -d '{"emoji":"string"}'
1fetch("http://localhost:8000/chats/example/messages/example/reactions", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "emoji": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/chats/example/messages/example/reactions",
5 json={"emoji":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /sign/envelopes/:envelope_id/recipients/:recipient_id

Edit a recipient

PATCH /sign/envelopes/:envelope_id/recipients/:recipient_id — edit a recipient (before send).

Handled by api_update_recipient
Parameters
envelope_id string · path
required
recipient_id string · path
required
Body · UpdateRecipientapplication/json
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
Responses
200Successful Response
PATCH /sign/envelopes/example/recipients/example
1curl -X PATCH "http://localhost:8000/sign/envelopes/example/recipients/example" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","email":"user@example.com","role":"string","recipient_type":null,"signer_mrn":"string","signing_order":1,"access_code":"string"}'
1fetch("http://localhost:8000/sign/envelopes/example/recipients/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "email": "user@example.com",
7 "role": "string",
8 "recipient_type": null,
9 "signer_mrn": "string",
10 "signing_order": 1,
11 "access_code": "string"
12}),
13})
14 .then((res) => res.json())
15 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/sign/envelopes/example/recipients/example",
5 json={"name":"string","email":"user@example.com","role":"string","recipient_type":null,"signer_mrn":"string","signing_order":1,"access_code":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /sign/envelopes/:envelope_id/recipients

Add a recipient

POST /sign/envelopes/:envelope_id/recipients — add a recipient (member or external guest).

Handled by api_create_recipient
Parameters
envelope_id string · path
required
Body · CreateRecipientapplication/json
name string · min length: 1 · max length: 200
required
email string · email
required
role string · min length: 1 · max length: 100
required
recipient_type
signer_mrn string
signing_order integer
access_code string · min length: 4 · max length: 64
propertyName anything
Responses
200Successful Response
POST /sign/envelopes/example/recipients
1curl -X POST "http://localhost:8000/sign/envelopes/example/recipients" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","email":"user@example.com","role":"string","recipient_type":null,"signer_mrn":"string","signing_order":1,"access_code":"string"}'
1fetch("http://localhost:8000/sign/envelopes/example/recipients", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "email": "user@example.com",
7 "role": "string",
8 "recipient_type": null,
9 "signer_mrn": "string",
10 "signing_order": 1,
11 "access_code": "string"
12}),
13})
14 .then((res) => res.json())
15 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/sign/envelopes/example/recipients",
5 json={"name":"string","email":"user@example.com","role":"string","recipient_type":null,"signer_mrn":"string","signing_order":1,"access_code":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /finance/bank-rules/:rule_id

Update a bank rule

Handled by handler
Parameters
rule_id string · path
required
Body · BankRuleapplication/json
name string · min length: 1 · max length: 100
required
match object
required
action object
required
propertyName anything
Responses
200Successful Response
PATCH /finance/bank-rules/example
1curl -X PATCH "http://localhost:8000/finance/bank-rules/example" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","match":{"description_contains":"string","direction":null,"amount_min":1.5,"amount_max":1.5},"action":{"account_code":"string","description":"string","entry_type":null}}'
1fetch("http://localhost:8000/finance/bank-rules/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "match": {
7 "description_contains": "string",
8 "direction": null,
9 "amount_min": 1.5,
10 "amount_max": 1.5
11 },
12 "action": {
13 "account_code": "string",
14 "description": "string",
15 "entry_type": null
16 }
17}),
18})
19 .then((res) => res.json())
20 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/finance/bank-rules/example",
5 json={"name":"string","match":{"description_contains":"string","direction":null,"amount_min":1.5,"amount_max":1.5},"action":{"account_code":"string","description":"string","entry_type":null}},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /finance/bank-imports

Import a bank feed

Handled by api_create_bank_import
Body · ImportBankFeedapplication/json
bank_account_id string · min length: 1
required
rows array
required
propertyName anything
Responses
200Successful Response
POST /finance/bank-imports
1curl -X POST "http://localhost:8000/finance/bank-imports" \
2 -H "Content-Type: application/json" \
3 -d '{"bank_account_id":"string","rows":[{"date":"string","description":"string","amount":1.5,"reference":"string"}]}'
1fetch("http://localhost:8000/finance/bank-imports", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "bank_account_id": "string",
6 "rows": [
7 {
8 "date": "string",
9 "description": "string",
10 "amount": 1.5,
11 "reference": "string"
12 }
13 ]
14}),
15})
16 .then((res) => res.json())
17 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/finance/bank-imports",
5 json={"bank_account_id":"string","rows":[{"date":"string","description":"string","amount":1.5,"reference":"string"}]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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.

Handled by api_create_entry_from_import
Parameters
import_id string · path
required
Body · CreateEntryFromImportapplication/json
account_code string · max length: 20
description string · max length: 500
entry_type
propertyName anything
Responses
200Successful Response
POST /finance/bank-imports/example/entries
1curl -X POST "http://localhost:8000/finance/bank-imports/example/entries" \
2 -H "Content-Type: application/json" \
3 -d '{"account_code":"string","description":"string","entry_type":null}'
1fetch("http://localhost:8000/finance/bank-imports/example/entries", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "account_code": "string",
6 "description": "string",
7 "entry_type": null
8}),
9})
10 .then((res) => res.json())
11 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/finance/bank-imports/example/entries",
5 json={"account_code":"string","description":"string","entry_type":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /finance/bank-connections

Connect a bank account

Handled by api_create_bank_connection
Body · ConnectBankAccountapplication/json
code string · min length: 1 · max length: 200
required
propertyName anything
Responses
200Successful Response
POST /finance/bank-connections
1curl -X POST "http://localhost:8000/finance/bank-connections" \
2 -H "Content-Type: application/json" \
3 -d '{"code":"string"}'
1fetch("http://localhost:8000/finance/bank-connections", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "code": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/finance/bank-connections",
5 json={"code":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /finance/reconciliations

Finalise a reconciliation

Handled by api_complete_reconciliation
Body · CompleteReconciliationapplication/json
bank_account_id string · min length: 1
required
period_start string · min length: 10
required
period_end string · min length: 10
required
statement_balance number
required
propertyName anything
Responses
200Successful Response
POST /finance/reconciliations
1curl -X POST "http://localhost:8000/finance/reconciliations" \
2 -H "Content-Type: application/json" \
3 -d '{"bank_account_id":"string","period_start":"string","period_end":"string","statement_balance":1.5}'
1fetch("http://localhost:8000/finance/reconciliations", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "bank_account_id": "string",
6 "period_start": "string",
7 "period_end": "string",
8 "statement_balance": 1.5
9}),
10})
11 .then((res) => res.json())
12 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/finance/reconciliations",
5 json={"bank_account_id":"string","period_start":"string","period_end":"string","statement_balance":1.5},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /finance/bank-rules

Create a bank rule

Handled by handler
Body · BankRuleapplication/json
name string · min length: 1 · max length: 100
required
match object
required
action object
required
propertyName anything
Responses
200Successful Response
POST /finance/bank-rules
1curl -X POST "http://localhost:8000/finance/bank-rules" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","match":{"description_contains":"string","direction":null,"amount_min":1.5,"amount_max":1.5},"action":{"account_code":"string","description":"string","entry_type":null}}'
1fetch("http://localhost:8000/finance/bank-rules", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "match": {
7 "description_contains": "string",
8 "direction": null,
9 "amount_min": 1.5,
10 "amount_max": 1.5
11 },
12 "action": {
13 "account_code": "string",
14 "description": "string",
15 "entry_type": null
16 }
17}),
18})
19 .then((res) => res.json())
20 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/finance/bank-rules",
5 json={"name":"string","match":{"description_contains":"string","direction":null,"amount_min":1.5,"amount_max":1.5},"action":{"account_code":"string","description":"string","entry_type":null}},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /calls/:id/recordings/:recording_id

Abort a recording

Abandon a recording: abort the R2 multipart upload and mark it failed. Host-only.

Handled by api_abort_recording
Parameters
id string · path
required
recording_id string · path
required
Body · AbortRecordingapplication/json
status
required
upload_id string · min length: 1 · max length: 512
propertyName anything
Responses
200Successful Response
PATCH /calls/example/recordings/example
1curl -X PATCH "http://localhost:8000/calls/example/recordings/example" \
2 -H "Content-Type: application/json" \
3 -d '{"status":null,"upload_id":"string"}'
1fetch("http://localhost:8000/calls/example/recordings/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "status": null,
6 "upload_id": "string"
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/calls/example/recordings/example",
5 json={"status":null,"upload_id":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /calls/:id/recordings

Start a recording

Handled by api_start_recording
Parameters
id string · path
required
Body · StartRecordingapplication/json
content_type string · max length: 100
propertyName anything
Responses
200Successful Response
POST /calls/example/recordings
1curl -X POST "http://localhost:8000/calls/example/recordings" \
2 -H "Content-Type: application/json" \
3 -d '{"content_type":"string"}'
1fetch("http://localhost:8000/calls/example/recordings", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "content_type": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/calls/example/recordings",
5 json={"content_type":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /calls/:id/recordings/:recording_id

Complete a recording

Finalize a recording: assemble the uploaded parts in R2 and mark it ready. Host-only.

Handled by api_complete_recording
Parameters
id string · path
required
recording_id string · path
required
Body · CompleteRecordingapplication/json
upload_id string · min length: 1 · max length: 512
required
parts array
required
size_bytes integer · min: 0
duration_seconds integer · min: 0
propertyName anything
Responses
200Successful Response
PUT /calls/example/recordings/example
1curl -X PUT "http://localhost:8000/calls/example/recordings/example" \
2 -H "Content-Type: application/json" \
3 -d '{"upload_id":"string","parts":[{"part_number":1,"etag":"string"}],"size_bytes":1,"duration_seconds":1}'
1fetch("http://localhost:8000/calls/example/recordings/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "upload_id": "string",
6 "parts": [
7 {
8 "part_number": 1,
9 "etag": "string"
10 }
11 ],
12 "size_bytes": 1,
13 "duration_seconds": 1
14}),
15})
16 .then((res) => res.json())
17 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/calls/example/recordings/example",
5 json={"upload_id":"string","parts":[{"part_number":1,"etag":"string"}],"size_bytes":1,"duration_seconds":1},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
GET /recovery-codes undocumented

/recovery-codes

Handled by list_recovery_codes
Responses
200Successful Response
GET /recovery-codes
1curl "http://localhost:8000/recovery-codes"
1fetch("http://localhost:8000/recovery-codes")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/recovery-codes")
4print(response.json())
200 Example Response
No Body
POST /recovery-codes undocumented

/recovery-codes

Handled by regenerate_recovery_codes
Responses
200Successful Response
POST /recovery-codes
1curl -X POST "http://localhost:8000/recovery-codes"
1fetch("http://localhost:8000/recovery-codes", { method: "POST" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.post("http://localhost:8000/recovery-codes")
4print(response.json())
200 Example Response
No Body
PATCH /finance/recurring-entries/:recurring_id

Update recurring entry

Handled by api_patch_recurring
Parameters
recurring_id string · path
required
Body · RecurringEntryDefapplication/json
name string · min length: 1 · max length: 200
required
type
required
frequency
required
next_date string · min length: 10
required
company_mrn string
contact_mrn string
items array
auto_approve
propertyName anything
Responses
200Successful Response
PATCH /finance/recurring-entries/example
1curl -X PATCH "http://localhost:8000/finance/recurring-entries/example" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","type":null,"frequency":null,"next_date":"string","company_mrn":"string","contact_mrn":"string","items":[{"description":"string","quantity":1.5,"unit_price":1.5,"discount":1.5,"amount":1.5,"account_code":"string","product_mrn":"string","taxes":[{"name":"string","rate":1.5,"amount":1.5,"reverse_charge":null}]}],"auto_approve":null}'
1fetch("http://localhost:8000/finance/recurring-entries/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "type": null,
7 "frequency": null,
8 "next_date": "string",
9 "company_mrn": "string",
10 "contact_mrn": "string",
11 "items": [
12 {
13 "description": "string",
14 "quantity": 1.5,
15 "unit_price": 1.5,
16 "discount": 1.5,
17 "amount": 1.5,
18 "account_code": "string",
19 "product_mrn": "string",
20 "taxes": [
21 {
22 "name": "string",
23 "rate": 1.5,
24 "amount": 1.5,
25 "reverse_charge": null
26 }
27 ]
28 }
29 ],
30 "auto_approve": null
31}),
32})
33 .then((res) => res.json())
34 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/finance/recurring-entries/example",
5 json={"name":"string","type":null,"frequency":null,"next_date":"string","company_mrn":"string","contact_mrn":"string","items":[{"description":"string","quantity":1.5,"unit_price":1.5,"discount":1.5,"amount":1.5,"account_code":"string","product_mrn":"string","taxes":[{"name":"string","rate":1.5,"amount":1.5,"reverse_charge":null}]}],"auto_approve":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /finance/recurring-entries

Create recurring entry

Handled by api_create_recurring
Body · RecurringEntryDefapplication/json
name string · min length: 1 · max length: 200
required
type
required
frequency
required
next_date string · min length: 10
required
company_mrn string
contact_mrn string
items array
auto_approve
propertyName anything
Responses
200Successful Response
POST /finance/recurring-entries
1curl -X POST "http://localhost:8000/finance/recurring-entries" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","type":null,"frequency":null,"next_date":"string","company_mrn":"string","contact_mrn":"string","items":[{"description":"string","quantity":1.5,"unit_price":1.5,"discount":1.5,"amount":1.5,"account_code":"string","product_mrn":"string","taxes":[{"name":"string","rate":1.5,"amount":1.5,"reverse_charge":null}]}],"auto_approve":null}'
1fetch("http://localhost:8000/finance/recurring-entries", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "type": null,
7 "frequency": null,
8 "next_date": "string",
9 "company_mrn": "string",
10 "contact_mrn": "string",
11 "items": [
12 {
13 "description": "string",
14 "quantity": 1.5,
15 "unit_price": 1.5,
16 "discount": 1.5,
17 "amount": 1.5,
18 "account_code": "string",
19 "product_mrn": "string",
20 "taxes": [
21 {
22 "name": "string",
23 "rate": 1.5,
24 "amount": 1.5,
25 "reverse_charge": null
26 }
27 ]
28 }
29 ],
30 "auto_approve": null
31}),
32})
33 .then((res) => res.json())
34 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/finance/recurring-entries",
5 json={"name":"string","type":null,"frequency":null,"next_date":"string","company_mrn":"string","contact_mrn":"string","items":[{"description":"string","quantity":1.5,"unit_price":1.5,"discount":1.5,"amount":1.5,"account_code":"string","product_mrn":"string","taxes":[{"name":"string","rate":1.5,"amount":1.5,"reverse_charge":null}]}],"auto_approve":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
GET /reports/burndown undocumented

/reports/burndown

Return burndown + burnup chart data for a schedule (or board-wide).

Handled by api_report_burndown
Responses
200Successful Response
GET /reports/burndown
1curl "http://localhost:8000/reports/burndown"
1fetch("http://localhost:8000/reports/burndown")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/reports/burndown")
4print(response.json())
200 Example Response
No Body
PATCH /finance/requests/:request_id

Approve or decline a request

PATCH /finance/requests/:id — approve (books the artifact) or decline.

Handled by api_decide_request
Parameters
request_id string · path
required
Body · DecideFinanceRequestapplication/json
status
required
reason string · max length: 1000
propertyName anything
Responses
200Successful Response
PATCH /finance/requests/example
1curl -X PATCH "http://localhost:8000/finance/requests/example" \
2 -H "Content-Type: application/json" \
3 -d '{"status":null,"reason":"string"}'
1fetch("http://localhost:8000/finance/requests/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "status": null,
6 "reason": "string"
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/finance/requests/example",
5 json={"status":null,"reason":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /finance/requests

File an expense claim, advance, or purchase request

POST /finance/requests — any portal member files their own request.

Handled by api_create_request
Body · CreateFinanceRequestapplication/json
kind
required
amount number
required
date string · min length: 10
required
description string · min length: 1 · max length: 2000
required
currency
category_code string · max length: 20
vendor string · max length: 200
needed_by string · min length: 10
receipts array
dimensions
propertyName anything
Responses
200Successful Response
POST /finance/requests
1curl -X POST "http://localhost:8000/finance/requests" \
2 -H "Content-Type: application/json" \
3 -d '{"kind":null,"amount":1.5,"date":"string","description":"string","currency":null,"category_code":"string","vendor":"string","needed_by":"string","receipts":[{"key":"string","filename":"string","url":"string","content_type":"string","size":1}],"dimensions":null}'
1fetch("http://localhost:8000/finance/requests", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "kind": null,
6 "amount": 1.5,
7 "date": "string",
8 "description": "string",
9 "currency": null,
10 "category_code": "string",
11 "vendor": "string",
12 "needed_by": "string",
13 "receipts": [
14 {
15 "key": "string",
16 "filename": "string",
17 "url": "string",
18 "content_type": "string",
19 "size": 1
20 }
21 ],
22 "dimensions": null
23}),
24})
25 .then((res) => res.json())
26 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/finance/requests",
5 json={"kind":null,"amount":1.5,"date":"string","description":"string","currency":null,"category_code":"string","vendor":"string","needed_by":"string","receipts":[{"key":"string","filename":"string","url":"string","content_type":"string","size":1}],"dimensions":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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.

Handled by api_pay_request
Parameters
request_id string · path
required
Body · PayFinanceRequestapplication/json
bank_account_id string
propertyName anything
Responses
200Successful Response
POST /finance/requests/example/payments
1curl -X POST "http://localhost:8000/finance/requests/example/payments" \
2 -H "Content-Type: application/json" \
3 -d '{"bank_account_id":"string"}'
1fetch("http://localhost:8000/finance/requests/example/payments", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "bank_account_id": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/finance/requests/example/payments",
5 json={"bank_account_id":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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).

Handled by api_post_request_message
Parameters
request_id string · path
required
Body · PostRequestMessageapplication/json
body string · min length: 1 · max length: 2000
required
propertyName anything
Responses
200Successful Response
POST /finance/requests/example/messages
1curl -X POST "http://localhost:8000/finance/requests/example/messages" \
2 -H "Content-Type: application/json" \
3 -d '{"body":"string"}'
1fetch("http://localhost:8000/finance/requests/example/messages", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "body": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/finance/requests/example/messages",
5 json={"body":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /requests/:update_id undocumented

/requests/:update_id

PUT /requests/:update_id — Approve or deny an install request via status field.

Handled by api_approve_or_deny_request
Parameters
update_id string · path
required
Responses
200Successful Response
PUT /requests/example
1curl -X PUT "http://localhost:8000/requests/example"
1fetch("http://localhost:8000/requests/example", { method: "PUT" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.put("http://localhost:8000/requests/example")
4print(response.json())
200 Example Response
No Body
DELETE /roles/:role_id undocumented

/roles/:role_id

DELETE /accounts/organisation/roles/:role_id — Delete a role.

Handled by api_delete_role
Parameters
role_id string · path
required
Responses
200Successful Response
DELETE /roles/example
1curl -X DELETE "http://localhost:8000/roles/example"
1fetch("http://localhost:8000/roles/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/roles/example")
4print(response.json())
200 Example Response
No Body
DELETE /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.

Handled by api_remove_role_member
Parameters
role_id string · path
required
member_id string · path
required
Responses
200Successful Response
DELETE /roles/example/members/example
1curl -X DELETE "http://localhost:8000/roles/example/members/example"
1fetch("http://localhost:8000/roles/example/members/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/roles/example/members/example")
4print(response.json())
200 Example Response
No Body
GET /roles undocumented

/roles

GET /roles — List custom roles for the workspace (admin view).

Handled by api_list_roles
Responses
200Successful Response
GET /roles
1curl "http://localhost:8000/roles"
1fetch("http://localhost:8000/roles")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/roles")
4print(response.json())
200 Example Response
No Body
POST /roles

Create role

POST /accounts/organisation/roles — Create a role.

Handled by api_create_role
Body · CreateRoleapplication/json
name string · min length: 1 · max length: 100
required
description string · max length: 500
propertyName anything
Responses
200Successful Response
POST /roles
1curl -X POST "http://localhost:8000/roles" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","description":"string"}'
1fetch("http://localhost:8000/roles", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "description": "string"
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/roles",
5 json={"name":"string","description":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /roles/:role_id/members

Assign member to role

POST /accounts/organisation/roles/:role_id/members — Assign member to role.

Handled by api_assign_role_member
Parameters
role_id string · path
required
Body · AssignRoleMemberapplication/json
member_id string · min length: 1
required
propertyName anything
Responses
200Successful Response
POST /roles/example/members
1curl -X POST "http://localhost:8000/roles/example/members" \
2 -H "Content-Type: application/json" \
3 -d '{"member_id":"string"}'
1fetch("http://localhost:8000/roles/example/members", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "member_id": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/roles/example/members",
5 json={"member_id":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /roles/:role_id undocumented

/roles/:role_id

PUT /accounts/organisation/roles/:role_id — Update role + permissions.

Handled by api_update_role
Parameters
role_id string · path
required
Responses
200Successful Response
PUT /roles/example
1curl -X PUT "http://localhost:8000/roles/example"
1fetch("http://localhost:8000/roles/example", { method: "PUT" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.put("http://localhost:8000/roles/example")
4print(response.json())
200 Example Response
No Body
PUT /roles/:role_id/default

Set role as default

Toggle whether a role is auto-assigned to new members. Body: {is_default: bool}

Handled by api_set_role_default
Parameters
role_id string · path
required
Body · UpdateRoleDefaultapplication/json
is_default
required
propertyName anything
Responses
200Successful Response
PUT /roles/example/default
1curl -X PUT "http://localhost:8000/roles/example/default" \
2 -H "Content-Type: application/json" \
3 -d '{"is_default":null}'
1fetch("http://localhost:8000/roles/example/default", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "is_default": null
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/roles/example/default",
5 json={"is_default":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
DELETE /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).

Handled by api_delete_room
Parameters
id string · path
required
Responses
200Successful Response
DELETE /rooms/example
1curl -X DELETE "http://localhost:8000/rooms/example"
1fetch("http://localhost:8000/rooms/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/rooms/example")
4print(response.json())
200 Example Response
No Body
DELETE /rooms/:id/members/:member_mrn undocumented

/rooms/:id/members/:member_mrn

Remove member from room.

Handled by api_remove_room_member
Parameters
id string · path
required
member_mrn string · path
required
Responses
200Successful Response
DELETE /rooms/example/members/example
1curl -X DELETE "http://localhost:8000/rooms/example/members/example"
1fetch("http://localhost:8000/rooms/example/members/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/rooms/example/members/example")
4print(response.json())
200 Example Response
No Body
DELETE /rooms/:id/sessions undocumented

/rooms/:id/sessions

Leave a room. Sets is_connected = FALSE.

Handled by api_leave_room
Parameters
id string · path
required
Responses
200Successful Response
DELETE /rooms/example/sessions
1curl -X DELETE "http://localhost:8000/rooms/example/sessions"
1fetch("http://localhost:8000/rooms/example/sessions", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/rooms/example/sessions")
4print(response.json())
200 Example Response
No Body
GET /rooms undocumented

/rooms

List rooms visible to the current member. Supports ?q= search and pagination.

Handled by api_list_rooms
Responses
200Successful Response
GET /rooms
1curl "http://localhost:8000/rooms"
1fetch("http://localhost:8000/rooms")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/rooms")
4print(response.json())
200 Example Response
No Body
GET /rooms/:id undocumented

/rooms/:id

Get room details + full member list with connection status.

Handled by api_get_room
Parameters
id string · path
required
Responses
200Successful Response
GET /rooms/example
1curl "http://localhost:8000/rooms/example"
1fetch("http://localhost:8000/rooms/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/rooms/example")
4print(response.json())
200 Example Response
No Body
GET /rooms/:id/members undocumented

/rooms/:id/members

List room members with connection/mute state.

Handled by api_list_room_members
Parameters
id string · path
required
Responses
200Successful Response
GET /rooms/example/members
1curl "http://localhost:8000/rooms/example/members"
1fetch("http://localhost:8000/rooms/example/members")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/rooms/example/members")
4print(response.json())
200 Example Response
No Body
PATCH /rooms/:id

Update a room

Update room name, description, settings, type.

Handled by api_update_room
Parameters
id string · path
required
Body · UpdateRoomapplication/json
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
Responses
200Successful Response
PATCH /rooms/example
1curl -X PATCH "http://localhost:8000/rooms/example" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","description":"string","type":null,"max_participants":1,"settings":{"mute_on_join":null}}'
1fetch("http://localhost:8000/rooms/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "description": "string",
7 "type": null,
8 "max_participants": 1,
9 "settings": {
10 "mute_on_join": null
11 }
12}),
13})
14 .then((res) => res.json())
15 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/rooms/example",
5 json={"name":"string","description":"string","type":null,"max_participants":1,"settings":{"mute_on_join":null}},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /rooms/:id/members/:member_mrn

Update room member role

Update member role (promote/demote admin).

Handled by api_update_room_member
Parameters
id string · path
required
member_mrn string · path
required
Body · UpdateMemberapplication/json
role
required
propertyName anything
Responses
200Successful Response
PATCH /rooms/example/members/example
1curl -X PATCH "http://localhost:8000/rooms/example/members/example" \
2 -H "Content-Type: application/json" \
3 -d '{"role":null}'
1fetch("http://localhost:8000/rooms/example/members/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "role": null
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/rooms/example/members/example",
5 json={"role":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /rooms

Create a room

Create a new room. Creator becomes room admin.

Handled by api_create_room
Body · CreateRoomapplication/json
name string · min length: 1 · max length: 50
required
description string · max length: 200
type
max_participants integer · min: 2 · max: 100
settings object
propertyName anything
Responses
200Successful Response
POST /rooms
1curl -X POST "http://localhost:8000/rooms" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","description":"string","type":null,"max_participants":1,"settings":{"mute_on_join":null}}'
1fetch("http://localhost:8000/rooms", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "description": "string",
7 "type": null,
8 "max_participants": 1,
9 "settings": {
10 "mute_on_join": null
11 }
12}),
13})
14 .then((res) => res.json())
15 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/rooms",
5 json={"name":"string","description":"string","type":null,"max_participants":1,"settings":{"mute_on_join":null}},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /rooms/:id/members

Add room members

Add member(s) to a room.

Handled by api_add_room_members
Parameters
id string · path
required
Body · AddMembersapplication/json
members array
required
propertyName anything
Responses
200Successful Response
POST /rooms/example/members
1curl -X POST "http://localhost:8000/rooms/example/members" \
2 -H "Content-Type: application/json" \
3 -d '{"members":["string"]}'
1fetch("http://localhost:8000/rooms/example/members", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "members": [
6 "string"
7 ]
8}),
9})
10 .then((res) => res.json())
11 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/rooms/example/members",
5 json={"members":["string"]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /rooms/:id/sessions undocumented

/rooms/:id/sessions

Join a room. Generates a LiveKit access token. Sets is_connected = TRUE.

Handled by api_join_room
Parameters
id string · path
required
Responses
200Successful Response
POST /rooms/example/sessions
1curl -X POST "http://localhost:8000/rooms/example/sessions"
1fetch("http://localhost:8000/rooms/example/sessions", { method: "POST" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.post("http://localhost:8000/rooms/example/sessions")
4print(response.json())
200 Example Response
No Body
POST /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.

Handled by api_refresh_room_token
Parameters
id string · path
required
Responses
200Successful Response
POST /rooms/example/token
1curl -X POST "http://localhost:8000/rooms/example/token"
1fetch("http://localhost:8000/rooms/example/token", { method: "POST" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.post("http://localhost:8000/rooms/example/token")
4print(response.json())
200 Example Response
No Body
POST /rooms/:id/members/:member_mrn/mute undocumented

/rooms/:id/members/:member_mrn/mute

Mute a participant (room admin only). Signals via platform WS.

Handled by api_force_mute_member
Parameters
id string · path
required
member_mrn string · path
required
Responses
200Successful Response
POST /rooms/example/members/example/mute
1curl -X POST "http://localhost:8000/rooms/example/members/example/mute"
1fetch("http://localhost:8000/rooms/example/members/example/mute", { method: "POST" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.post("http://localhost:8000/rooms/example/members/example/mute")
4print(response.json())
200 Example Response
No Body
PUT /rooms/session-state undocumented

/rooms/session-state

PUT /rooms/session-state — Sync client-side mute state into session for restore on refresh.

Handled by api_update_session_state
Responses
200Successful Response
PUT /rooms/session-state
1curl -X PUT "http://localhost:8000/rooms/session-state"
1fetch("http://localhost:8000/rooms/session-state", { method: "PUT" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.put("http://localhost:8000/rooms/session-state")
4print(response.json())
200 Example Response
No Body
DELETE /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.

Handled by api_delete_schedule
Parameters
schedule_id string · path
required
Responses
200Successful Response
DELETE /schedules/example
1curl -X DELETE "http://localhost:8000/schedules/example"
1fetch("http://localhost:8000/schedules/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/schedules/example")
4print(response.json())
200 Example Response
No Body
GET /schedules undocumented

/schedules

GET /schedules?board_id=...&q=... — list schedules for a board, optionally filtered by name.

Handled by api_list_schedules
Responses
200Successful Response
GET /schedules
1curl "http://localhost:8000/schedules"
1fetch("http://localhost:8000/schedules")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/schedules")
4print(response.json())
200 Example Response
No Body
POST /schedules

Create a schedule

Handled by api_create_schedule
Body · CreateScheduleapplication/json
board_id string
required
name string · min length: 1 · max length: 200
required
start_date string · min length: 1
required
end_date string · min length: 1
required
goal string · max length: 500
description string · max length: 5000
status
propertyName anything
Responses
200Successful Response
POST /schedules
1curl -X POST "http://localhost:8000/schedules" \
2 -H "Content-Type: application/json" \
3 -d '{"board_id":"string","name":"string","start_date":"string","end_date":"string","goal":"string","description":"string","status":null}'
1fetch("http://localhost:8000/schedules", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "board_id": "string",
6 "name": "string",
7 "start_date": "string",
8 "end_date": "string",
9 "goal": "string",
10 "description": "string",
11 "status": null
12}),
13})
14 .then((res) => res.json())
15 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/schedules",
5 json={"board_id":"string","name":"string","start_date":"string","end_date":"string","goal":"string","description":"string","status":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /schedules/:schedule_id

Update a schedule

Update a schedule's mutable fields.

Handled by api_update_schedule
Parameters
schedule_id string · path
required
Body · UpdateScheduleapplication/json
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
Responses
200Successful Response
PUT /schedules/example
1curl -X PUT "http://localhost:8000/schedules/example" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","goal":"string","description":"string","status":null,"start_date":"string","end_date":"string"}'
1fetch("http://localhost:8000/schedules/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "goal": "string",
7 "description": "string",
8 "status": null,
9 "start_date": "string",
10 "end_date": "string"
11}),
12})
13 .then((res) => res.json())
14 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/schedules/example",
5 json={"name":"string","goal":"string","description":"string","status":null,"start_date":"string","end_date":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
DELETE /scoring/rules/:rule_id undocumented

/scoring/rules/:rule_id

Handled by api_delete_scoring_rule
Parameters
rule_id string · path
required
Responses
200Successful Response
DELETE /scoring/rules/example
1curl -X DELETE "http://localhost:8000/scoring/rules/example"
1fetch("http://localhost:8000/scoring/rules/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/scoring/rules/example")
4print(response.json())
200 Example Response
No Body
GET /scoring/rules undocumented

/scoring/rules

Handled by api_list_scoring_rules
Responses
200Successful Response
GET /scoring/rules
1curl "http://localhost:8000/scoring/rules"
1fetch("http://localhost:8000/scoring/rules")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/scoring/rules")
4print(response.json())
200 Example Response
No Body
GET /scoring/rules/:rule_id undocumented

/scoring/rules/:rule_id

Handled by api_get_scoring_rule
Parameters
rule_id string · path
required
Responses
200Successful Response
GET /scoring/rules/example
1curl "http://localhost:8000/scoring/rules/example"
1fetch("http://localhost:8000/scoring/rules/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/scoring/rules/example")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_compute_score
Parameters
entity_type string · path
required
entity_id string · path
required
Responses
200Successful Response
GET /scoring/example/example
1curl "http://localhost:8000/scoring/example/example"
1fetch("http://localhost:8000/scoring/example/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/scoring/example/example")
4print(response.json())
200 Example Response
No Body
POST /scoring/rules

Create a scoring rule

Handled by api_create_scoring_rule
Body · CreateScoringRuleapplication/json
name string · min length: 1 · max length: 200
required
entity_type
required
rules array
required
thresholds array
enabled
propertyName anything
Responses
200Successful Response
POST /scoring/rules
1curl -X POST "http://localhost:8000/scoring/rules" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","entity_type":null,"rules":[{"signal":"string","op":null,"value":"string","points":1,"label":"string"}],"thresholds":[{"score_gte":1,"score_lte":1,"action":"string","label":"string"}],"enabled":null}'
1fetch("http://localhost:8000/scoring/rules", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "entity_type": null,
7 "rules": [
8 {
9 "signal": "string",
10 "op": null,
11 "value": "string",
12 "points": 1,
13 "label": "string"
14 }
15 ],
16 "thresholds": [
17 {
18 "score_gte": 1,
19 "score_lte": 1,
20 "action": "string",
21 "label": "string"
22 }
23 ],
24 "enabled": null
25}),
26})
27 .then((res) => res.json())
28 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/scoring/rules",
5 json={"name":"string","entity_type":null,"rules":[{"signal":"string","op":null,"value":"string","points":1,"label":"string"}],"thresholds":[{"score_gte":1,"score_lte":1,"action":"string","label":"string"}],"enabled":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /scoring/rules/:rule_id

Update a scoring rule

Handled by api_update_scoring_rule
Parameters
rule_id string · path
required
Body · UpdateScoringRuleapplication/json
name string · min length: 1 · max length: 200
rules array
thresholds array
enabled
propertyName anything
Responses
200Successful Response
PUT /scoring/rules/example
1curl -X PUT "http://localhost:8000/scoring/rules/example" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","rules":[{"signal":"string","op":null,"value":"string","points":1,"label":"string"}],"thresholds":[{"score_gte":1,"score_lte":1,"action":"string","label":"string"}],"enabled":null}'
1fetch("http://localhost:8000/scoring/rules/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "rules": [
7 {
8 "signal": "string",
9 "op": null,
10 "value": "string",
11 "points": 1,
12 "label": "string"
13 }
14 ],
15 "thresholds": [
16 {
17 "score_gte": 1,
18 "score_lte": 1,
19 "action": "string",
20 "label": "string"
21 }
22 ],
23 "enabled": null
24}),
25})
26 .then((res) => res.json())
27 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/scoring/rules/example",
5 json={"name":"string","rules":[{"signal":"string","op":null,"value":"string","points":1,"label":"string"}],"thresholds":[{"score_gte":1,"score_lte":1,"action":"string","label":"string"}],"enabled":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
GET /search undocumented

/search

GET /search?app=tasks&q=PL-417&types=task: search one app, best match first.

Handled by search
Responses
200Successful Response
GET /search
1curl "http://localhost:8000/search"
1fetch("http://localhost:8000/search")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/search")
4print(response.json())
200 Example Response
No Body
POST /search

Search one app

POST /search with {app, q, types, filters}: the same search with a structured body.

Handled by create_search
Body · SearchRequestapplication/json
app string · min length: 1 · max length: 64
required
q string · max length: 2000
required
types array
filters object
propertyName anything
Responses
200Successful Response
POST /search
1curl -X POST "http://localhost:8000/search" \
2 -H "Content-Type: application/json" \
3 -d '{"app":"string","q":"string","types":["string"],"filters":{"type":"string","owner":"string","after":"string","before":"string","min_size":"string","max_size":"string"}}'
1fetch("http://localhost:8000/search", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "app": "string",
6 "q": "string",
7 "types": [
8 "string"
9 ],
10 "filters": {
11 "type": "string",
12 "owner": "string",
13 "after": "string",
14 "before": "string",
15 "min_size": "string",
16 "max_size": "string"
17 }
18}),
19})
20 .then((res) => res.json())
21 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/search",
5 json={"app":"string","q":"string","types":["string"],"filters":{"type":"string","owner":"string","after":"string","before":"string","min_size":"string","max_size":"string"}},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
DELETE /segments/:segment_id undocumented

/segments/:segment_id

DELETE /segments/:segment_id — delete a segment.

Handled by api_delete_segment
Parameters
segment_id string · path
required
Responses
200Successful Response
DELETE /segments/example
1curl -X DELETE "http://localhost:8000/segments/example"
1fetch("http://localhost:8000/segments/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/segments/example")
4print(response.json())
200 Example Response
No Body
DELETE /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.

Handled by api_remove_segment_member
Parameters
segment_id string · path
required
member_id string · path
required
Responses
200Successful Response
DELETE /segments/example/members/example
1curl -X DELETE "http://localhost:8000/segments/example/members/example"
1fetch("http://localhost:8000/segments/example/members/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/segments/example/members/example")
4print(response.json())
200 Example Response
No Body
GET /segments undocumented

/segments

GET /segments — list segments.

Handled by api_list_segments
Responses
200Successful Response
GET /segments
1curl "http://localhost:8000/segments"
1fetch("http://localhost:8000/segments")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/segments")
4print(response.json())
200 Example Response
No Body
GET /segments/:segment_id undocumented

/segments/:segment_id

GET /segments/:segment_id — get segment with resolved members.

Handled by api_get_segment
Parameters
segment_id string · path
required
Responses
200Successful Response
GET /segments/example
1curl "http://localhost:8000/segments/example"
1fetch("http://localhost:8000/segments/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/segments/example")
4print(response.json())
200 Example Response
No Body
POST /segments

Create a segment

POST /segments — create a segment (static or dynamic).

Handled by api_create_segment
Body · CreateSegmentapplication/json
name string · min length: 1 · max length: 100
required
description string · max length: 500
type
entity_type
filter object
members array
propertyName anything
Responses
200Successful Response
POST /segments
1curl -X POST "http://localhost:8000/segments" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","description":"string","type":null,"entity_type":null,"filter":{"entity_type":null,"tags":["string"],"domain":"string","industry":"string","size":["string"],"source":"string","owner_mrn":"string","state":null,"has_open_conversation":null,"csat_below":1,"last_order_within_days":1,"total_paid_orders_gte":1},"members":[{"type":null,"id":"string"}]}'
1fetch("http://localhost:8000/segments", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "description": "string",
7 "type": null,
8 "entity_type": null,
9 "filter": {
10 "entity_type": null,
11 "tags": [
12 "string"
13 ],
14 "domain": "string",
15 "industry": "string",
16 "size": [
17 "string"
18 ],
19 "source": "string",
20 "owner_mrn": "string",
21 "state": null,
22 "has_open_conversation": null,
23 "csat_below": 1,
24 "last_order_within_days": 1,
25 "total_paid_orders_gte": 1
26 },
27 "members": [
28 {
29 "type": null,
30 "id": "string"
31 }
32 ]
33}),
34})
35 .then((res) => res.json())
36 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/segments",
5 json={"name":"string","description":"string","type":null,"entity_type":null,"filter":{"entity_type":null,"tags":["string"],"domain":"string","industry":"string","size":["string"],"source":"string","owner_mrn":"string","state":null,"has_open_conversation":null,"csat_below":1,"last_order_within_days":1,"total_paid_orders_gte":1},"members":[{"type":null,"id":"string"}]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /segments/:segment_id/members

Add member to segment

POST /segments/:segment_id/members — add a contact/company to a static segment.

Handled by api_add_segment_member
Parameters
segment_id string · path
required
Body · AddSegmentMemberapplication/json
type
required
id string · min length: 1
required
propertyName anything
Responses
200Successful Response
POST /segments/example/members
1curl -X POST "http://localhost:8000/segments/example/members" \
2 -H "Content-Type: application/json" \
3 -d '{"type":null,"id":"string"}'
1fetch("http://localhost:8000/segments/example/members", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "type": null,
6 "id": "string"
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/segments/example/members",
5 json={"type":null,"id":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /segments/:segment_id

Update a segment

PUT /segments/:segment_id — update a segment (name, description, or rules).

Handled by api_update_segment
Parameters
segment_id string · path
required
Body · UpdateSegmentapplication/json
name string · min length: 1 · max length: 100
description string · max length: 500
filter object
propertyName anything
Responses
200Successful Response
PUT /segments/example
1curl -X PUT "http://localhost:8000/segments/example" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","description":"string","filter":{"entity_type":null,"tags":["string"],"domain":"string","industry":"string","size":["string"],"source":"string","owner_mrn":"string","state":null,"has_open_conversation":null,"csat_below":1,"last_order_within_days":1,"total_paid_orders_gte":1}}'
1fetch("http://localhost:8000/segments/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "description": "string",
7 "filter": {
8 "entity_type": null,
9 "tags": [
10 "string"
11 ],
12 "domain": "string",
13 "industry": "string",
14 "size": [
15 "string"
16 ],
17 "source": "string",
18 "owner_mrn": "string",
19 "state": null,
20 "has_open_conversation": null,
21 "csat_below": 1,
22 "last_order_within_days": 1,
23 "total_paid_orders_gte": 1
24 }
25}),
26})
27 .then((res) => res.json())
28 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/segments/example",
5 json={"name":"string","description":"string","filter":{"entity_type":null,"tags":["string"],"domain":"string","industry":"string","size":["string"],"source":"string","owner_mrn":"string","state":null,"has_open_conversation":null,"csat_below":1,"last_order_within_days":1,"total_paid_orders_gte":1}},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /chats/:id/settings

Update chat settings

PATCH /chats/:id/settings — per-chat settings for the caller (mute).

Handled by api_update_settings
Parameters
id string · path
required
Body · UpdateChatSettingsapplication/json
muted_until string
propertyName anything
Responses
200Successful Response
PATCH /chats/example/settings
1curl -X PATCH "http://localhost:8000/chats/example/settings" \
2 -H "Content-Type: application/json" \
3 -d '{"muted_until":"string"}'
1fetch("http://localhost:8000/chats/example/settings", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "muted_until": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/chats/example/settings",
5 json={"muted_until":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /finance/tax-rates/:tax_id

Update tax preset

Handled by handler
Parameters
tax_id string · path
required
Body · TaxRatePresetapplication/json
name string · min length: 1 · max length: 100
required
rates array
required
propertyName anything
Responses
200Successful Response
PATCH /finance/tax-rates/example
1curl -X PATCH "http://localhost:8000/finance/tax-rates/example" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","rates":[{"name":"string","rate":1.5,"amount":1.5,"reverse_charge":null}]}'
1fetch("http://localhost:8000/finance/tax-rates/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "rates": [
7 {
8 "name": "string",
9 "rate": 1.5,
10 "amount": 1.5,
11 "reverse_charge": null
12 }
13 ]
14}),
15})
16 .then((res) => res.json())
17 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/finance/tax-rates/example",
5 json={"name":"string","rates":[{"name":"string","rate":1.5,"amount":1.5,"reverse_charge":null}]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /finance/payment-terms/:term_id

Update payment term

Handled by handler
Parameters
term_id string · path
required
Body · PaymentTermPresetapplication/json
name string · min length: 1 · max length: 100
required
days integer · min: 0
required
early_discount_rate number
early_discount_days integer
propertyName anything
Responses
200Successful Response
PATCH /finance/payment-terms/example
1curl -X PATCH "http://localhost:8000/finance/payment-terms/example" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","days":1,"early_discount_rate":1.5,"early_discount_days":1}'
1fetch("http://localhost:8000/finance/payment-terms/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "days": 1,
7 "early_discount_rate": 1.5,
8 "early_discount_days": 1
9}),
10})
11 .then((res) => res.json())
12 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/finance/payment-terms/example",
5 json={"name":"string","days":1,"early_discount_rate":1.5,"early_discount_days":1},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /finance/tax-rates

Create tax preset

Handled by handler
Body · TaxRatePresetapplication/json
name string · min length: 1 · max length: 100
required
rates array
required
propertyName anything
Responses
200Successful Response
POST /finance/tax-rates
1curl -X POST "http://localhost:8000/finance/tax-rates" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","rates":[{"name":"string","rate":1.5,"amount":1.5,"reverse_charge":null}]}'
1fetch("http://localhost:8000/finance/tax-rates", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "rates": [
7 {
8 "name": "string",
9 "rate": 1.5,
10 "amount": 1.5,
11 "reverse_charge": null
12 }
13 ]
14}),
15})
16 .then((res) => res.json())
17 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/finance/tax-rates",
5 json={"name":"string","rates":[{"name":"string","rate":1.5,"amount":1.5,"reverse_charge":null}]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /finance/payment-terms

Create payment term

Handled by handler
Body · PaymentTermPresetapplication/json
name string · min length: 1 · max length: 100
required
days integer · min: 0
required
early_discount_rate number
early_discount_days integer
propertyName anything
Responses
200Successful Response
POST /finance/payment-terms
1curl -X POST "http://localhost:8000/finance/payment-terms" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","days":1,"early_discount_rate":1.5,"early_discount_days":1}'
1fetch("http://localhost:8000/finance/payment-terms", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "days": 1,
7 "early_discount_rate": 1.5,
8 "early_discount_days": 1
9}),
10})
11 .then((res) => res.json())
12 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/finance/payment-terms",
5 json={"name":"string","days":1,"early_discount_rate":1.5,"early_discount_days":1},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /finance/settings

Update core settings

Handled by api_update_settings
Body · UpdateSettingsapplication/json
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
Responses
200Successful Response
PUT /finance/settings
1curl -X PUT "http://localhost:8000/finance/settings" \
2 -H "Content-Type: application/json" \
3 -d '{"base_currency":null,"fiscal_year_start":1,"accounting_enabled":null,"number_prefixes":{"quote":"string","purchase_order":"string","order":"string","invoice":"string","bill":"string","credit_note":"string","journal":"string"},"sequential_numbers":null,"default_accounts":{"accounts_receivable":"string","accounts_payable":"string","cash":"string","tax_payable":"string","accrued_expenses":"string","customer_deposits":"string","vendor_prepayments":"string","vendor_credits":"string","employee_advances":"string","withholding_tax_receivable":"string","withholding_tax_payable":"string","fx_gains":"string","fx_losses":"string","unrealized_fx_asset":"string","unrealized_fx_liability":"string","sales_discounts":"string","retained_earnings":"string","cogs":"string","inventory":"string","inventory_adjustments":"string"},"invoice_template":{"logo_url":"string","logo_key":"string","company_name":"string","company_address":"string","accent_color":"string","footer_text":"string","bank_details":"string"}}'
1fetch("http://localhost:8000/finance/settings", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "base_currency": null,
6 "fiscal_year_start": 1,
7 "accounting_enabled": null,
8 "number_prefixes": {
9 "quote": "string",
10 "purchase_order": "string",
11 "order": "string",
12 "invoice": "string",
13 "bill": "string",
14 "credit_note": "string",
15 "journal": "string"
16 },
17 "sequential_numbers": null,
18 "default_accounts": {
19 "accounts_receivable": "string",
20 "accounts_payable": "string",
21 "cash": "string",
22 "tax_payable": "string",
23 "accrued_expenses": "string",
24 "customer_deposits": "string",
25 "vendor_prepayments": "string",
26 "vendor_credits": "string",
27 "employee_advances": "string",
28 "withholding_tax_receivable": "string",
29 "withholding_tax_payable": "string",
30 "fx_gains": "string",
31 "fx_losses": "string",
32 "unrealized_fx_asset": "string",
33 "unrealized_fx_liability": "string",
34 "sales_discounts": "string",
35 "retained_earnings": "string",
36 "cogs": "string",
37 "inventory": "string",
38 "inventory_adjustments": "string"
39 },
40 "invoice_template": {
41 "logo_url": "string",
42 "logo_key": "string",
43 "company_name": "string",
44 "company_address": "string",
45 "accent_color": "string",
46 "footer_text": "string",
47 "bank_details": "string"
48 }
49}),
50})
51 .then((res) => res.json())
52 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/finance/settings",
5 json={"base_currency":null,"fiscal_year_start":1,"accounting_enabled":null,"number_prefixes":{"quote":"string","purchase_order":"string","order":"string","invoice":"string","bill":"string","credit_note":"string","journal":"string"},"sequential_numbers":null,"default_accounts":{"accounts_receivable":"string","accounts_payable":"string","cash":"string","tax_payable":"string","accrued_expenses":"string","customer_deposits":"string","vendor_prepayments":"string","vendor_credits":"string","employee_advances":"string","withholding_tax_receivable":"string","withholding_tax_payable":"string","fx_gains":"string","fx_losses":"string","unrealized_fx_asset":"string","unrealized_fx_liability":"string","sales_discounts":"string","retained_earnings":"string","cogs":"string","inventory":"string","inventory_adjustments":"string"},"invoice_template":{"logo_url":"string","logo_key":"string","company_name":"string","company_address":"string","accent_color":"string","footer_text":"string","bank_details":"string"}},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
GET /shared undocumented

/shared

Handled by api_list_shared_with_me
Responses
200Successful Response
GET /shared
1curl "http://localhost:8000/shared"
1fetch("http://localhost:8000/shared")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/shared")
4print(response.json())
200 Example Response
No Body
DELETE /shares/:share_id undocumented

/shares/:share_id

Handled by api_delete_share
Parameters
share_id string · path
required
Responses
200Successful Response
DELETE /shares/example
1curl -X DELETE "http://localhost:8000/shares/example"
1fetch("http://localhost:8000/shares/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/shares/example")
4print(response.json())
200 Example Response
No Body
GET /shares undocumented

/shares

Handled by api_list_shares
Responses
200Successful Response
GET /shares
1curl "http://localhost:8000/shares"
1fetch("http://localhost:8000/shares")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/shares")
4print(response.json())
200 Example Response
No Body
GET /shares/:share_id undocumented

/shares/:share_id

Handled by api_get_share
Parameters
share_id string · path
required
Responses
200Successful Response
GET /shares/example
1curl "http://localhost:8000/shares/example"
1fetch("http://localhost:8000/shares/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/shares/example")
4print(response.json())
200 Example Response
No Body
PATCH /shares/:share_id

Update a share link

Handled by api_update_share
Parameters
share_id string · path
required
Body · UpdateShareapplication/json
password string · min length: 4 · max length: 128
expires_at string
max_downloads integer
is_active
propertyName anything
Responses
200Successful Response
PATCH /shares/example
1curl -X PATCH "http://localhost:8000/shares/example" \
2 -H "Content-Type: application/json" \
3 -d '{"password":"string","expires_at":"string","max_downloads":1,"is_active":null}'
1fetch("http://localhost:8000/shares/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "password": "string",
6 "expires_at": "string",
7 "max_downloads": 1,
8 "is_active": null
9}),
10})
11 .then((res) => res.json())
12 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/shares/example",
5 json={"password":"string","expires_at":"string","max_downloads":1,"is_active":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /shares

Create a share link

Handled by api_create_share
Body · CreateShareapplication/json
slug string · min length: 1 · max length: 200
required
propertyName anything
Responses
200Successful Response
POST /shares
1curl -X POST "http://localhost:8000/shares" \
2 -H "Content-Type: application/json" \
3 -d '{"slug":"string"}'
1fetch("http://localhost:8000/shares", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "slug": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/shares",
5 json={"slug":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
DELETE /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.

Handled by api_delete_document
Parameters
envelope_id string · path
required
document_id string · path
required
Responses
200Successful Response
DELETE /sign/envelopes/example/documents/example
1curl -X DELETE "http://localhost:8000/sign/envelopes/example/documents/example"
1fetch("http://localhost:8000/sign/envelopes/example/documents/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/sign/envelopes/example/documents/example")
4print(response.json())
200 Example Response
No Body
DELETE /sign/envelopes/:envelope_id undocumented

/sign/envelopes/:envelope_id

DELETE /sign/envelopes/:envelope_id — delete a draft/template (sent envelopes are voided, not deleted).

Handled by api_delete_envelope
Parameters
envelope_id string · path
required
Responses
200Successful Response
DELETE /sign/envelopes/example
1curl -X DELETE "http://localhost:8000/sign/envelopes/example"
1fetch("http://localhost:8000/sign/envelopes/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/sign/envelopes/example")
4print(response.json())
200 Example Response
No Body
DELETE /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.

Handled by api_revoke_public_link
Parameters
envelope_id string · path
required
link_id string · path
required
Responses
200Successful Response
DELETE /sign/templates/example/links/example
1curl -X DELETE "http://localhost:8000/sign/templates/example/links/example"
1fetch("http://localhost:8000/sign/templates/example/links/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/sign/templates/example/links/example")
4print(response.json())
200 Example Response
No Body
DELETE /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.

Handled by api_delete_export
Parameters
envelope_id string · path
required
target string · path
required
Responses
200Successful Response
DELETE /sign/envelopes/example/exports/example
1curl -X DELETE "http://localhost:8000/sign/envelopes/example/exports/example"
1fetch("http://localhost:8000/sign/envelopes/example/exports/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/sign/envelopes/example/exports/example")
4print(response.json())
200 Example Response
No Body
DELETE /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.

Handled by api_delete_field
Parameters
envelope_id string · path
required
field_id string · path
required
Responses
200Successful Response
DELETE /sign/envelopes/example/fields/example
1curl -X DELETE "http://localhost:8000/sign/envelopes/example/fields/example"
1fetch("http://localhost:8000/sign/envelopes/example/fields/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/sign/envelopes/example/fields/example")
4print(response.json())
200 Example Response
No Body
DELETE /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).

Handled by api_delete_recipient
Parameters
envelope_id string · path
required
recipient_id string · path
required
Responses
200Successful Response
DELETE /sign/envelopes/example/recipients/example
1curl -X DELETE "http://localhost:8000/sign/envelopes/example/recipients/example"
1fetch("http://localhost:8000/sign/envelopes/example/recipients/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/sign/envelopes/example/recipients/example")
4print(response.json())
200 Example Response
No Body
GET /sign/envelopes undocumented

/sign/envelopes

GET /sign/envelopes — list documents (non-templates by default; ?is_template=true, ?status=).

Handled by api_list_envelopes
Responses
200Successful Response
GET /sign/envelopes
1curl "http://localhost:8000/sign/envelopes"
1fetch("http://localhost:8000/sign/envelopes")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/sign/envelopes")
4print(response.json())
200 Example Response
No Body
GET /sign/envelopes/:envelope_id undocumented

/sign/envelopes/:envelope_id

GET /sign/envelopes/:envelope_id — envelope + its fields + recipients.

Handled by api_get_envelope
Parameters
envelope_id string · path
required
Responses
200Successful Response
GET /sign/envelopes/example
1curl "http://localhost:8000/sign/envelopes/example"
1fetch("http://localhost:8000/sign/envelopes/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/sign/envelopes/example")
4print(response.json())
200 Example Response
No Body
GET /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).

Handled by api_get_source
Parameters
envelope_id string · path
required
Responses
200Successful Response
GET /sign/envelopes/example/source
1curl "http://localhost:8000/sign/envelopes/example/source"
1fetch("http://localhost:8000/sign/envelopes/example/source")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/sign/envelopes/example/source")
4print(response.json())
200 Example Response
No Body
GET /sign/envelopes/:envelope_id/documents undocumented

/sign/envelopes/:envelope_id/documents

GET /sign/envelopes/:envelope_id/documents — the envelope's source PDFs in order.

Handled by api_list_documents
Parameters
envelope_id string · path
required
Responses
200Successful Response
GET /sign/envelopes/example/documents
1curl "http://localhost:8000/sign/envelopes/example/documents"
1fetch("http://localhost:8000/sign/envelopes/example/documents")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/sign/envelopes/example/documents")
4print(response.json())
200 Example Response
No Body
GET /sign/envelopes/:envelope_id/audit undocumented

/sign/envelopes/:envelope_id/audit

GET /sign/envelopes/:envelope_id/audit — the envelope's chronological audit trail.

Handled by api_get_audit
Parameters
envelope_id string · path
required
Responses
200Successful Response
GET /sign/envelopes/example/audit
1curl "http://localhost:8000/sign/envelopes/example/audit"
1fetch("http://localhost:8000/sign/envelopes/example/audit")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/sign/envelopes/example/audit")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_get_audit_integrity
Parameters
envelope_id string · path
required
Responses
200Successful Response
GET /sign/envelopes/example/audit/integrity
1curl "http://localhost:8000/sign/envelopes/example/audit/integrity"
1fetch("http://localhost:8000/sign/envelopes/example/audit/integrity")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/sign/envelopes/example/audit/integrity")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_get_values
Parameters
envelope_id string · path
required
Responses
200Successful Response
GET /sign/envelopes/example/values
1curl "http://localhost:8000/sign/envelopes/example/values"
1fetch("http://localhost:8000/sign/envelopes/example/values")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/sign/envelopes/example/values")
4print(response.json())
200 Example Response
No Body
GET /sign/envelopes/:envelope_id/document undocumented

/sign/envelopes/:envelope_id/document

GET /sign/envelopes/:envelope_id/document — presigned URL for the sealed PDF.

Handled by api_get_document
Parameters
envelope_id string · path
required
Responses
200Successful Response
GET /sign/envelopes/example/document
1curl "http://localhost:8000/sign/envelopes/example/document"
1fetch("http://localhost:8000/sign/envelopes/example/document")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/sign/envelopes/example/document")
4print(response.json())
200 Example Response
No Body
GET /sign/envelopes/:envelope_id/certificate undocumented

/sign/envelopes/:envelope_id/certificate

GET /sign/envelopes/:envelope_id/certificate — presigned URL for the Certificate of Completion.

Handled by api_get_certificate
Parameters
envelope_id string · path
required
Responses
200Successful Response
GET /sign/envelopes/example/certificate
1curl "http://localhost:8000/sign/envelopes/example/certificate"
1fetch("http://localhost:8000/sign/envelopes/example/certificate")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/sign/envelopes/example/certificate")
4print(response.json())
200 Example Response
No Body
GET /sign/templates undocumented

/sign/templates

GET /sign/templates — list reusable templates (sugar for ?is_template=true).

Handled by api_list_templates
Responses
200Successful Response
GET /sign/templates
1curl "http://localhost:8000/sign/templates"
1fetch("http://localhost:8000/sign/templates")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/sign/templates")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_list_template_usages
Parameters
envelope_id string · path
required
Responses
200Successful Response
GET /sign/templates/example/usages
1curl "http://localhost:8000/sign/templates/example/usages"
1fetch("http://localhost:8000/sign/templates/example/usages")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/sign/templates/example/usages")
4print(response.json())
200 Example Response
No Body
GET /sign/templates/:envelope_id/links undocumented

/sign/templates/:envelope_id/links

GET /sign/templates/:envelope_id/links — this template's self-serve links.

Handled by api_list_public_links
Parameters
envelope_id string · path
required
Responses
200Successful Response
GET /sign/templates/example/links
1curl "http://localhost:8000/sign/templates/example/links"
1fetch("http://localhost:8000/sign/templates/example/links")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/sign/templates/example/links")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_list_signatories
Responses
200Successful Response
GET /sign/signatories
1curl "http://localhost:8000/sign/signatories"
1fetch("http://localhost:8000/sign/signatories")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/sign/signatories")
4print(response.json())
200 Example Response
No Body
GET /sign/signatories/:email undocumented

/sign/signatories/:email

GET /sign/signatories/:email — one signatory's profile (see _signatory_profile).

Handled by api_get_signatory
Parameters
email string · path
required
Responses
200Successful Response
GET /sign/signatories/example
1curl "http://localhost:8000/sign/signatories/example"
1fetch("http://localhost:8000/sign/signatories/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/sign/signatories/example")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_get_statistics
Responses
200Successful Response
GET /sign/statistics
1curl "http://localhost:8000/sign/statistics"
1fetch("http://localhost:8000/sign/statistics")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/sign/statistics")
4print(response.json())
200 Example Response
No Body
GET /sign/jurisdictions undocumented

/sign/jurisdictions

GET /sign/jurisdictions — picker options + carve-out warnings (static config).

Handled by api_get_jurisdictions
Responses
200Successful Response
GET /sign/jurisdictions
1curl "http://localhost:8000/sign/jurisdictions"
1fetch("http://localhost:8000/sign/jurisdictions")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/sign/jurisdictions")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_get_settings
Responses
200Successful Response
GET /sign/settings
1curl "http://localhost:8000/sign/settings"
1fetch("http://localhost:8000/sign/settings")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/sign/settings")
4print(response.json())
200 Example Response
No Body
GET /sign/envelopes/:envelope_id/fields undocumented

/sign/envelopes/:envelope_id/fields

GET /sign/envelopes/:envelope_id/fields — list field placements.

Handled by api_list_fields
Parameters
envelope_id string · path
required
Responses
200Successful Response
GET /sign/envelopes/example/fields
1curl "http://localhost:8000/sign/envelopes/example/fields"
1fetch("http://localhost:8000/sign/envelopes/example/fields")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/sign/envelopes/example/fields")
4print(response.json())
200 Example Response
No Body
GET /sign/envelopes/:envelope_id/recipients undocumented

/sign/envelopes/:envelope_id/recipients

GET /sign/envelopes/:envelope_id/recipients — list recipients + their status.

Handled by api_list_recipients
Parameters
envelope_id string · path
required
Responses
200Successful Response
GET /sign/envelopes/example/recipients
1curl "http://localhost:8000/sign/envelopes/example/recipients"
1fetch("http://localhost:8000/sign/envelopes/example/recipients")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/sign/envelopes/example/recipients")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_get_recipient_link
Parameters
envelope_id string · path
required
recipient_id string · path
required
Responses
200Successful Response
GET /sign/envelopes/example/recipients/example/link
1curl "http://localhost:8000/sign/envelopes/example/recipients/example/link"
1fetch("http://localhost:8000/sign/envelopes/example/recipients/example/link")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/sign/envelopes/example/recipients/example/link")
4print(response.json())
200 Example Response
No Body
POST /sign/envelopes/:envelope_id/reminders undocumented

/sign/envelopes/:envelope_id/reminders

POST /sign/envelopes/:envelope_id/reminders — remind recipients who haven't signed.

Handled by api_send_reminders
Parameters
envelope_id string · path
required
Responses
200Successful Response
POST /sign/envelopes/example/reminders
1curl -X POST "http://localhost:8000/sign/envelopes/example/reminders"
1fetch("http://localhost:8000/sign/envelopes/example/reminders", { method: "POST" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.post("http://localhost:8000/sign/envelopes/example/reminders")
4print(response.json())
200 Example Response
No Body
POST /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.

Handled by api_broadcast_template
Parameters
envelope_id string · path
required
Responses
200Successful Response
POST /sign/templates/example/broadcasts
1curl -X POST "http://localhost:8000/sign/templates/example/broadcasts"
1fetch("http://localhost:8000/sign/templates/example/broadcasts", { method: "POST" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.post("http://localhost:8000/sign/templates/example/broadcasts")
4print(response.json())
200 Example Response
No Body
PATCH /decks/:id

Update a deck

PATCH /decks/:id. Title, content, thumbnail, or restore from trash.

Handled by api_update_deck
Parameters
id string · path
required
Body · UpdateDeckapplication/json
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
Responses
200Successful Response
PATCH /decks/example
1curl -X PATCH "http://localhost:8000/decks/example" \
2 -H "Content-Type: application/json" \
3 -d '{"title":"string","deck_json":{"v":1,"size":{"w":1,"h":1},"theme":null,"slides":[null]},"slide_count":1,"thumbnail_key":"string","deleted":null}'
1fetch("http://localhost:8000/decks/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "title": "string",
6 "deck_json": {
7 "v": 1,
8 "size": {
9 "w": 1,
10 "h": 1
11 },
12 "theme": null,
13 "slides": [
14 null
15 ]
16 },
17 "slide_count": 1,
18 "thumbnail_key": "string",
19 "deleted": null
20}),
21})
22 .then((res) => res.json())
23 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/decks/example",
5 json={"title":"string","deck_json":{"v":1,"size":{"w":1,"h":1},"theme":null,"slides":[null]},"slide_count":1,"thumbnail_key":"string","deleted":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /decks

Create a deck

POST /decks. Create a blank deck.

Handled by api_create_deck
Body · CreateDeckapplication/json
title string · min length: 1 · max length: 200
propertyName anything
Responses
200Successful Response
POST /decks
1curl -X POST "http://localhost:8000/decks" \
2 -H "Content-Type: application/json" \
3 -d '{"title":"string"}'
1fetch("http://localhost:8000/decks", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "title": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/decks",
5 json={"title":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /decks/:id/assets

Register a deck image

POST /decks/:id/assets. Register an uploaded image. Gate loaded ctx.authz.deck.

Handled by api_create_asset
Parameters
id string · path
required
Body · CreateAssetapplication/json
asset_id string · min length: 6 · max length: 64
required
storage_key string · min length: 1 · max length: 512
required
filename string · min length: 1 · max length: 255
required
content_type string · min length: 1 · max length: 100
required
size_bytes integer · min: 0
required
width integer · min: 0
height integer · min: 0
propertyName anything
Responses
200Successful Response
POST /decks/example/assets
1curl -X POST "http://localhost:8000/decks/example/assets" \
2 -H "Content-Type: application/json" \
3 -d '{"asset_id":"string","storage_key":"string","filename":"string","content_type":"string","size_bytes":1,"width":1,"height":1}'
1fetch("http://localhost:8000/decks/example/assets", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "asset_id": "string",
6 "storage_key": "string",
7 "filename": "string",
8 "content_type": "string",
9 "size_bytes": 1,
10 "width": 1,
11 "height": 1
12}),
13})
14 .then((res) => res.json())
15 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/decks/example/assets",
5 json={"asset_id":"string","storage_key":"string","filename":"string","content_type":"string","size_bytes":1,"width":1,"height":1},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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.

Handled by api_import_media
Parameters
id string · path
required
Body · ImportMediaapplication/json
collection string · min length: 1 · max length: 20
required
slug string · min length: 1 · max length: 200
required
propertyName anything
Responses
200Successful Response
POST /decks/example/media
1curl -X POST "http://localhost:8000/decks/example/media" \
2 -H "Content-Type: application/json" \
3 -d '{"collection":"string","slug":"string"}'
1fetch("http://localhost:8000/decks/example/media", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "collection": "string",
6 "slug": "string"
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/decks/example/media",
5 json={"collection":"string","slug":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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.

Handled by api_create_spellschema
Body · CreateSpellSchemaapplication/json
route string · min length: 1
required
method string
propertyName anything
Responses
200Successful Response
POST /spellschemas
1curl -X POST "http://localhost:8000/spellschemas" \
2 -H "Content-Type: application/json" \
3 -d '{"route":"string","method":"string"}'
1fetch("http://localhost:8000/spellschemas", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "route": "string",
6 "method": "string"
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/spellschemas",
5 json={"route":"string","method":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
GET /spell-runs/:run_id undocumented

/spell-runs/:run_id

Handled by api_get_run
Parameters
run_id string · path
required
Responses
200Successful Response
GET /spell-runs/example
1curl "http://localhost:8000/spell-runs/example"
1fetch("http://localhost:8000/spell-runs/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/spell-runs/example")
4print(response.json())
200 Example Response
No Body
DELETE /spells/:spell_id undocumented

/spells/:spell_id

Handled by api_delete_spell
Parameters
spell_id string · path
required
Responses
200Successful Response
DELETE /spells/example
1curl -X DELETE "http://localhost:8000/spells/example"
1fetch("http://localhost:8000/spells/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/spells/example")
4print(response.json())
200 Example Response
No Body
GET /spells undocumented

/spells

Handled by api_list_spells
Responses
200Successful Response
GET /spells
1curl "http://localhost:8000/spells"
1fetch("http://localhost:8000/spells")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/spells")
4print(response.json())
200 Example Response
No Body
GET /spells/:spell_id undocumented

/spells/:spell_id

Handled by api_get_spell
Parameters
spell_id string · path
required
Responses
200Successful Response
GET /spells/example
1curl "http://localhost:8000/spells/example"
1fetch("http://localhost:8000/spells/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/spells/example")
4print(response.json())
200 Example Response
No Body
GET /spells/:spell_id/runs undocumented

/spells/:spell_id/runs

Handled by api_list_runs
Parameters
spell_id string · path
required
Responses
200Successful Response
GET /spells/example/runs
1curl "http://localhost:8000/spells/example/runs"
1fetch("http://localhost:8000/spells/example/runs")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/spells/example/runs")
4print(response.json())
200 Example Response
No Body
POST /spells

Create a spell

Handled by api_create_spell
Body · CreateSpellapplication/json
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
Responses
200Successful Response
POST /spells
1curl -X POST "http://localhost:8000/spells" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","description":"string","trigger":{"events":["string"],"schedule":null,"where":null},"chain":[{"macro":"string","args":null,"output_as":"string","note":"string"}],"enabled":null,"format":null,"source":"string"}'
1fetch("http://localhost:8000/spells", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "description": "string",
7 "trigger": {
8 "events": [
9 "string"
10 ],
11 "schedule": null,
12 "where": null
13 },
14 "chain": [
15 {
16 "macro": "string",
17 "args": null,
18 "output_as": "string",
19 "note": "string"
20 }
21 ],
22 "enabled": null,
23 "format": null,
24 "source": "string"
25}),
26})
27 .then((res) => res.json())
28 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/spells",
5 json={"name":"string","description":"string","trigger":{"events":["string"],"schedule":null,"where":null},"chain":[{"macro":"string","args":null,"output_as":"string","note":"string"}],"enabled":null,"format":null,"source":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /spells/:spell_id/test

Test a spell (dry run)

Dry-run a spell with a sample event payload.

Handled by api_test_spell
Parameters
spell_id string · path
required
Body · TestSpellapplication/json
payload
required
event_name string
propertyName anything
Responses
200Successful Response
POST /spells/example/test
1curl -X POST "http://localhost:8000/spells/example/test" \
2 -H "Content-Type: application/json" \
3 -d '{"payload":null,"event_name":"string"}'
1fetch("http://localhost:8000/spells/example/test", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "payload": null,
6 "event_name": "string"
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/spells/example/test",
5 json={"payload":null,"event_name":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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.

Handled by api_spellbook_transform
Body · SpellbookTransformapplication/json
source string · max length: 100000
spell
propertyName anything
Responses
200Successful Response
POST /wands/spellbook
1curl -X POST "http://localhost:8000/wands/spellbook" \
2 -H "Content-Type: application/json" \
3 -d '{"source":"string","spell":null}'
1fetch("http://localhost:8000/wands/spellbook", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "source": "string",
6 "spell": null
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/wands/spellbook",
5 json={"source":"string","spell":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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.

Handled by api_create_schedule_preview
Body · SchedulePreviewapplication/json
text string · min length: 1 · max length: 200
required
timezone string · max length: 64
propertyName anything
Responses
200Successful Response
POST /wands/schedule-previews
1curl -X POST "http://localhost:8000/wands/schedule-previews" \
2 -H "Content-Type: application/json" \
3 -d '{"text":"string","timezone":"string"}'
1fetch("http://localhost:8000/wands/schedule-previews", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "text": "string",
6 "timezone": "string"
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/wands/schedule-previews",
5 json={"text":"string","timezone":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /spells/:spell_id

Update a spell

Handled by api_update_spell
Parameters
spell_id string · path
required
Body · UpdateSpellapplication/json
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
Responses
200Successful Response
PUT /spells/example
1curl -X PUT "http://localhost:8000/spells/example" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","description":"string","trigger":{"events":["string"],"schedule":null,"where":null},"chain":[{"macro":"string","args":null,"output_as":"string","note":"string"}],"enabled":null,"format":null,"source":"string"}'
1fetch("http://localhost:8000/spells/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "description": "string",
7 "trigger": {
8 "events": [
9 "string"
10 ],
11 "schedule": null,
12 "where": null
13 },
14 "chain": [
15 {
16 "macro": "string",
17 "args": null,
18 "output_as": "string",
19 "note": "string"
20 }
21 ],
22 "enabled": null,
23 "format": null,
24 "source": "string"
25}),
26})
27 .then((res) => res.json())
28 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/spells/example",
5 json={"name":"string","description":"string","trigger":{"events":["string"],"schedule":null,"where":null},"chain":[{"macro":"string","args":null,"output_as":"string","note":"string"}],"enabled":null,"format":null,"source":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
DELETE /tables/trash undocumented

/tables/trash

DELETE /tables/trash, permanently delete every trashed table the caller manages.

Handled by api_empty_trash
Responses
200Successful Response
DELETE /tables/trash
1curl -X DELETE "http://localhost:8000/tables/trash"
1fetch("http://localhost:8000/tables/trash", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/tables/trash")
4print(response.json())
200 Example Response
No Body
DELETE /tables/trash/:table_id undocumented

/tables/trash/:table_id

DELETE /tables/trash/:table_id, permanently delete a trashed table.

Handled by api_purge_table
Parameters
table_id string · path
required
Responses
200Successful Response
DELETE /tables/trash/example
1curl -X DELETE "http://localhost:8000/tables/trash/example"
1fetch("http://localhost:8000/tables/trash/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/tables/trash/example")
4print(response.json())
200 Example Response
No Body
DELETE /tables/:table_id undocumented

/tables/:table_id

DELETE /tables/:table_id, move a table to the trash. Grants stay so it can be restored.

Handled by api_delete_table
Parameters
table_id string · path
required
Responses
200Successful Response
DELETE /tables/example
1curl -X DELETE "http://localhost:8000/tables/example"
1fetch("http://localhost:8000/tables/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/tables/example")
4print(response.json())
200 Example Response
No Body
DELETE /tables/:table_id/sheets/:sheet_id undocumented

/tables/:table_id/sheets/:sheet_id

DELETE /tables/:table_id/sheets/:sheet_id — remove one sheet.

Handled by api_delete_sheet
Parameters
table_id string · path
required
sheet_id string · path
required
Responses
200Successful Response
DELETE /tables/example/sheets/example
1curl -X DELETE "http://localhost:8000/tables/example/sheets/example"
1fetch("http://localhost:8000/tables/example/sheets/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/tables/example/sheets/example")
4print(response.json())
200 Example Response
No Body
GET /tables undocumented

/tables

GET /tables — list tables for the workspace.

Handled by api_list_tables
Responses
200Successful Response
GET /tables
1curl "http://localhost:8000/tables"
1fetch("http://localhost:8000/tables")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/tables")
4print(response.json())
200 Example Response
No Body
GET /tables/trash undocumented

/tables/trash

GET /tables/trash, the trashed tables the caller may restore.

Handled by api_list_trash
Responses
200Successful Response
GET /tables/trash
1curl "http://localhost:8000/tables/trash"
1fetch("http://localhost:8000/tables/trash")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/tables/trash")
4print(response.json())
200 Example Response
No Body
GET /tables/:table_id undocumented

/tables/:table_id

GET /tables/:table_id — get a single table with data.

Handled by api_get_table
Parameters
table_id string · path
required
Responses
200Successful Response
GET /tables/example
1curl "http://localhost:8000/tables/example"
1fetch("http://localhost:8000/tables/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/tables/example")
4print(response.json())
200 Example Response
No Body
GET /tables/:table_id/versions undocumented

/tables/:table_id/versions

GET /tables/:table_id/versions — list version history.

Handled by api_list_versions
Parameters
table_id string · path
required
Responses
200Successful Response
GET /tables/example/versions
1curl "http://localhost:8000/tables/example/versions"
1fetch("http://localhost:8000/tables/example/versions")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/tables/example/versions")
4print(response.json())
200 Example Response
No Body
GET /tables/:table_id/exports/:format undocumented

/tables/:table_id/exports/:format

GET /tables/:table_id/exports/:format: the workbook as an .ods download.

Handled by api_export_table
Parameters
table_id string · path
required
format string · path
required
Responses
200Successful Response
GET /tables/example/exports/example
1curl "http://localhost:8000/tables/example/exports/example"
1fetch("http://localhost:8000/tables/example/exports/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/tables/example/exports/example")
4print(response.json())
200 Example Response
No Body
GET /tables/:table_id/presence undocumented

/tables/:table_id/presence

GET /tables/:table_id/presence — get active collaborators.

Handled by api_get_presence
Parameters
table_id string · path
required
Responses
200Successful Response
GET /tables/example/presence
1curl "http://localhost:8000/tables/example/presence"
1fetch("http://localhost:8000/tables/example/presence")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/tables/example/presence")
4print(response.json())
200 Example Response
No Body
PATCH /tables/:table_id

Update a table

PATCH /tables/:table_id — update table title, icon, or data.

Handled by api_update_table
Parameters
table_id string · path
required
Body · UpdateTableapplication/json
title string · min length: 1 · max length: 500
icon string · max length: 100
icon_type
data string
visibility
deleted
propertyName anything
Responses
200Successful Response
PATCH /tables/example
1curl -X PATCH "http://localhost:8000/tables/example" \
2 -H "Content-Type: application/json" \
3 -d '{"title":"string","icon":"string","icon_type":null,"data":"string","visibility":null,"deleted":null}'
1fetch("http://localhost:8000/tables/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "title": "string",
6 "icon": "string",
7 "icon_type": null,
8 "data": "string",
9 "visibility": null,
10 "deleted": null
11}),
12})
13 .then((res) => res.json())
14 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/tables/example",
5 json={"title":"string","icon":"string","icon_type":null,"data":"string","visibility":null,"deleted":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /tables

Create a table

POST /tables — create a new table.

Handled by api_create_table
Body · CreateTableapplication/json
title string · min length: 1 · max length: 500
icon string · max length: 100
icon_type
data string
propertyName anything
Responses
200Successful Response
POST /tables
1curl -X POST "http://localhost:8000/tables" \
2 -H "Content-Type: application/json" \
3 -d '{"title":"string","icon":"string","icon_type":null,"data":"string"}'
1fetch("http://localhost:8000/tables", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "title": "string",
6 "icon": "string",
7 "icon_type": null,
8 "data": "string"
9}),
10})
11 .then((res) => res.json())
12 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/tables",
5 json={"title":"string","icon":"string","icon_type":null,"data":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /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.

Handled by api_upsert_sheet
Parameters
table_id string · path
required
sheet_id string · path
required
Body · UpsertSheetapplication/json
name string · min length: 1 · max length: 200
position integer · min: 0 · max: 500
doc string
propertyName anything
Responses
200Successful Response
PUT /tables/example/sheets/example
1curl -X PUT "http://localhost:8000/tables/example/sheets/example" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","position":1,"doc":"string"}'
1fetch("http://localhost:8000/tables/example/sheets/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "position": 1,
7 "doc": "string"
8}),
9})
10 .then((res) => res.json())
11 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/tables/example/sheets/example",
5 json={"name":"string","position":1,"doc":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /tables/:table_id/presence undocumented

/tables/:table_id/presence

PUT /tables/:table_id/presence — update cursor position.

Handled by api_update_presence
Parameters
table_id string · path
required
Responses
200Successful Response
PUT /tables/example/presence
1curl -X PUT "http://localhost:8000/tables/example/presence"
1fetch("http://localhost:8000/tables/example/presence", { method: "PUT" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.put("http://localhost:8000/tables/example/presence")
4print(response.json())
200 Example Response
No Body
DELETE /targets/:target_id undocumented

/targets/:target_id

Handled by api_delete_target
Parameters
target_id string · path
required
Responses
200Successful Response
DELETE /targets/example
1curl -X DELETE "http://localhost:8000/targets/example"
1fetch("http://localhost:8000/targets/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/targets/example")
4print(response.json())
200 Example Response
No Body
GET /targets undocumented

/targets

Handled by api_list_targets
Responses
200Successful Response
GET /targets
1curl "http://localhost:8000/targets"
1fetch("http://localhost:8000/targets")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/targets")
4print(response.json())
200 Example Response
No Body
GET /targets/leaderboard undocumented

/targets/leaderboard

Handled by api_leaderboard
Responses
200Successful Response
GET /targets/leaderboard
1curl "http://localhost:8000/targets/leaderboard"
1fetch("http://localhost:8000/targets/leaderboard")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/targets/leaderboard")
4print(response.json())
200 Example Response
No Body
GET /targets/:target_id undocumented

/targets/:target_id

Handled by api_get_target
Parameters
target_id string · path
required
Responses
200Successful Response
GET /targets/example
1curl "http://localhost:8000/targets/example"
1fetch("http://localhost:8000/targets/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/targets/example")
4print(response.json())
200 Example Response
No Body
POST /targets

Create a target

Handled by api_create_target
Body · CreateTargetapplication/json
type
required
owner_mrn string
required
pipeline_id string
period
required
period_start string
required
period_end string
required
target_value number
required
currency string · min length: 3 · max length: 3
propertyName anything
Responses
200Successful Response
POST /targets
1curl -X POST "http://localhost:8000/targets" \
2 -H "Content-Type: application/json" \
3 -d '{"type":null,"owner_mrn":"string","pipeline_id":"string","period":null,"period_start":"string","period_end":"string","target_value":1.5,"currency":"string"}'
1fetch("http://localhost:8000/targets", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "type": null,
6 "owner_mrn": "string",
7 "pipeline_id": "string",
8 "period": null,
9 "period_start": "string",
10 "period_end": "string",
11 "target_value": 1.5,
12 "currency": "string"
13}),
14})
15 .then((res) => res.json())
16 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/targets",
5 json={"type":null,"owner_mrn":"string","pipeline_id":"string","period":null,"period_start":"string","period_end":"string","target_value":1.5,"currency":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /targets/:target_id

Update a target

Handled by api_update_target
Parameters
target_id string · path
required
Body · UpdateTargetapplication/json
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
Responses
200Successful Response
PUT /targets/example
1curl -X PUT "http://localhost:8000/targets/example" \
2 -H "Content-Type: application/json" \
3 -d '{"type":null,"owner_mrn":"string","period":null,"period_start":"string","period_end":"string","target_value":1.5,"currency":"string","status":null}'
1fetch("http://localhost:8000/targets/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "type": null,
6 "owner_mrn": "string",
7 "period": null,
8 "period_start": "string",
9 "period_end": "string",
10 "target_value": 1.5,
11 "currency": "string",
12 "status": null
13}),
14})
15 .then((res) => res.json())
16 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/targets/example",
5 json={"type":null,"owner_mrn":"string","period":null,"period_start":"string","period_end":"string","target_value":1.5,"currency":"string","status":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
DELETE /tasks/:task_id undocumented

/tasks/:task_id

Handled by api_delete_task
Parameters
task_id string · path
required
Responses
200Successful Response
DELETE /tasks/example
1curl -X DELETE "http://localhost:8000/tasks/example"
1fetch("http://localhost:8000/tasks/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/tasks/example")
4print(response.json())
200 Example Response
No Body
DELETE /tasks

Delete tasks in bulk

Delete multiple tasks by ID.

Handled by api_bulk_delete_tasks
Body · BulkDeleteTasksapplication/json
task_ids array
required
propertyName anything
Responses
200Successful Response
DELETE /tasks
1curl -X DELETE "http://localhost:8000/tasks" \
2 -H "Content-Type: application/json" \
3 -d '{"task_ids":["string"]}'
1fetch("http://localhost:8000/tasks", {
2 method: "DELETE",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "task_ids": [
6 "string"
7 ]
8}),
9})
10 .then((res) => res.json())
11 .then(console.log);
1import requests
2
3response = requests.delete(
4 "http://localhost:8000/tasks",
5 json={"task_ids":["string"]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
DELETE /tasks/:task_id/links/:link_id undocumented

/tasks/:task_id/links/:link_id

Handled by api_delete_task_link
Parameters
task_id string · path
required
link_id string · path
required
Responses
200Successful Response
DELETE /tasks/example/links/example
1curl -X DELETE "http://localhost:8000/tasks/example/links/example"
1fetch("http://localhost:8000/tasks/example/links/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/tasks/example/links/example")
4print(response.json())
200 Example Response
No Body
GET /tasks undocumented

/tasks

Handled by api_list_tasks
Responses
200Successful Response
GET /tasks
1curl "http://localhost:8000/tasks"
1fetch("http://localhost:8000/tasks")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/tasks")
4print(response.json())
200 Example Response
No Body
PATCH /tasks/:task_id

Update a task

Handled by api_update_task
Parameters
task_id string · path
required
Body · UpdateTaskapplication/json
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
Responses
200Successful Response
PATCH /tasks/example
1curl -X PATCH "http://localhost:8000/tasks/example" \
2 -H "Content-Type: application/json" \
3 -d '{"title":"string","description":"string","column_name":"string","assignee_mrn":"string","reporter_mrn":"string","reviewer_mrn":"string","priority":null,"topic_id":"string","due_date":"string","start_date":"string","estimate_hours":null,"logged_hours":null,"wiki":"string","blocked_by":"string","position":null,"schedule_id":"string","deliverable_id":"string","parent_id":"string","size":1,"on_board":null,"completed":null,"labels":["string"],"attachments":[{"key":"string","url":"string","mrn":"string","filename":"string","content_type":"string","size":1}],"watchers":["string"],"add_comment":{"text":"string"}}'
1fetch("http://localhost:8000/tasks/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "title": "string",
6 "description": "string",
7 "column_name": "string",
8 "assignee_mrn": "string",
9 "reporter_mrn": "string",
10 "reviewer_mrn": "string",
11 "priority": null,
12 "topic_id": "string",
13 "due_date": "string",
14 "start_date": "string",
15 "estimate_hours": null,
16 "logged_hours": null,
17 "wiki": "string",
18 "blocked_by": "string",
19 "position": null,
20 "schedule_id": "string",
21 "deliverable_id": "string",
22 "parent_id": "string",
23 "size": 1,
24 "on_board": null,
25 "completed": null,
26 "labels": [
27 "string"
28 ],
29 "attachments": [
30 {
31 "key": "string",
32 "url": "string",
33 "mrn": "string",
34 "filename": "string",
35 "content_type": "string",
36 "size": 1
37 }
38 ],
39 "watchers": [
40 "string"
41 ],
42 "add_comment": {
43 "text": "string"
44 }
45}),
46})
47 .then((res) => res.json())
48 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/tasks/example",
5 json={"title":"string","description":"string","column_name":"string","assignee_mrn":"string","reporter_mrn":"string","reviewer_mrn":"string","priority":null,"topic_id":"string","due_date":"string","start_date":"string","estimate_hours":null,"logged_hours":null,"wiki":"string","blocked_by":"string","position":null,"schedule_id":"string","deliverable_id":"string","parent_id":"string","size":1,"on_board":null,"completed":null,"labels":["string"],"attachments":[{"key":"string","url":"string","mrn":"string","filename":"string","content_type":"string","size":1}],"watchers":["string"],"add_comment":{"text":"string"}},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /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.

Handled by api_transfer_tasks
Body · TransferTasksapplication/json
task_ids array
required
board_id string · min length: 1
required
columns array
propertyName anything
Responses
200Successful Response
PATCH /tasks
1curl -X PATCH "http://localhost:8000/tasks" \
2 -H "Content-Type: application/json" \
3 -d '{"task_ids":["string"],"board_id":"string","columns":[{"source":"string","target":"string"}]}'
1fetch("http://localhost:8000/tasks", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "task_ids": [
6 "string"
7 ],
8 "board_id": "string",
9 "columns": [
10 {
11 "source": "string",
12 "target": "string"
13 }
14 ]
15}),
16})
17 .then((res) => res.json())
18 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/tasks",
5 json={"task_ids":["string"],"board_id":"string","columns":[{"source":"string","target":"string"}]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /tasks

Create a task

Handled by api_create_task
Body · CreateTaskapplication/json
title string · min length: 1 · max length: 200
required
board_id string
required
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
Responses
200Successful Response
POST /tasks
1curl -X POST "http://localhost:8000/tasks" \
2 -H "Content-Type: application/json" \
3 -d '{"title":"string","board_id":"string","column_name":"string","parent_id":"string","on_board":null,"priority":null,"description":"string","topic_id":"string","labels":["string"],"attachments":[{"key":"string","url":"string","mrn":"string","filename":"string","content_type":"string","size":1}],"assignee_mrn":"string","schedule_id":"string","due_date":"string","size":1,"source_mrn":"string"}'
1fetch("http://localhost:8000/tasks", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "title": "string",
6 "board_id": "string",
7 "column_name": "string",
8 "parent_id": "string",
9 "on_board": null,
10 "priority": null,
11 "description": "string",
12 "topic_id": "string",
13 "labels": [
14 "string"
15 ],
16 "attachments": [
17 {
18 "key": "string",
19 "url": "string",
20 "mrn": "string",
21 "filename": "string",
22 "content_type": "string",
23 "size": 1
24 }
25 ],
26 "assignee_mrn": "string",
27 "schedule_id": "string",
28 "due_date": "string",
29 "size": 1,
30 "source_mrn": "string"
31}),
32})
33 .then((res) => res.json())
34 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/tasks",
5 json={"title":"string","board_id":"string","column_name":"string","parent_id":"string","on_board":null,"priority":null,"description":"string","topic_id":"string","labels":["string"],"attachments":[{"key":"string","url":"string","mrn":"string","filename":"string","content_type":"string","size":1}],"assignee_mrn":"string","schedule_id":"string","due_date":"string","size":1,"source_mrn":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /tasks/:task_id/links

Link two tasks

POST /tasks/:task_id/links — relate this task to another (blocks/relates/duplicates).

Handled by api_create_task_link
Parameters
task_id string · path
required
Body · CreateTaskLinkapplication/json
to_task_id string · min length: 1
required
kind
required
propertyName anything
Responses
200Successful Response
POST /tasks/example/links
1curl -X POST "http://localhost:8000/tasks/example/links" \
2 -H "Content-Type: application/json" \
3 -d '{"to_task_id":"string","kind":null}'
1fetch("http://localhost:8000/tasks/example/links", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "to_task_id": "string",
6 "kind": null
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/tasks/example/links",
5 json={"to_task_id":"string","kind":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /sign/templates

Create a reusable template

POST /sign/templates — create a reusable template.

Handled by api_create_template
Body · CreateEnvelopeapplication/json
title string · min length: 1 · max length: 300
required
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
Responses
200Successful Response
POST /sign/templates
1curl -X POST "http://localhost:8000/sign/templates" \
2 -H "Content-Type: application/json" \
3 -d '{"title":"string","subject":"string","message":"string","template_id":"string","signing_order_mode":null,"jurisdiction":"string","is_template":null,"source_mrn":"string"}'
1fetch("http://localhost:8000/sign/templates", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "title": "string",
6 "subject": "string",
7 "message": "string",
8 "template_id": "string",
9 "signing_order_mode": null,
10 "jurisdiction": "string",
11 "is_template": null,
12 "source_mrn": "string"
13}),
14})
15 .then((res) => res.json())
16 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/sign/templates",
5 json={"title":"string","subject":"string","message":"string","template_id":"string","signing_order_mode":null,"jurisdiction":"string","is_template":null,"source_mrn":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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.

Handled by api_create_public_link
Parameters
envelope_id string · path
required
Body · CreatePublicLinkapplication/json
expires_at string
max_submissions integer
propertyName anything
Responses
200Successful Response
POST /sign/templates/example/links
1curl -X POST "http://localhost:8000/sign/templates/example/links" \
2 -H "Content-Type: application/json" \
3 -d '{"expires_at":"string","max_submissions":1}'
1fetch("http://localhost:8000/sign/templates/example/links", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "expires_at": "string",
6 "max_submissions": 1
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/sign/templates/example/links",
5 json={"expires_at":"string","max_submissions":1},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
DELETE /tickits/:id undocumented

/tickits/:id

Handled by api_delete_tickit
Parameters
id string · path
required
Responses
200Successful Response
DELETE /tickits/example
1curl -X DELETE "http://localhost:8000/tickits/example"
1fetch("http://localhost:8000/tickits/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/tickits/example")
4print(response.json())
200 Example Response
No Body
GET /tickits undocumented

/tickits

Handled by api_list_tickits
Responses
200Successful Response
GET /tickits
1curl "http://localhost:8000/tickits"
1fetch("http://localhost:8000/tickits")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/tickits")
4print(response.json())
200 Example Response
No Body
GET /tickits/days undocumented

/tickits/days

Handled by api_day_markers
Responses
200Successful Response
GET /tickits/days
1curl "http://localhost:8000/tickits/days"
1fetch("http://localhost:8000/tickits/days")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/tickits/days")
4print(response.json())
200 Example Response
No Body
PATCH /tickits/:id

Update a tickit

Handled by api_update_tickit
Parameters
id string · path
required
Body · UpdateTickitapplication/json
title string · min length: 1 · max length: 140
due_on string · max length: 10
urgency
completed
propertyName anything
Responses
200Successful Response
PATCH /tickits/example
1curl -X PATCH "http://localhost:8000/tickits/example" \
2 -H "Content-Type: application/json" \
3 -d '{"title":"string","due_on":"string","urgency":null,"completed":null}'
1fetch("http://localhost:8000/tickits/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "title": "string",
6 "due_on": "string",
7 "urgency": null,
8 "completed": null
9}),
10})
11 .then((res) => res.json())
12 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/tickits/example",
5 json={"title":"string","due_on":"string","urgency":null,"completed":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /tickits

Add a tickit

Handled by api_create_tickit
Body · CreateTickitapplication/json
title string · min length: 1 · max length: 140
required
day string · min length: 10 · max length: 10
propertyName anything
Responses
200Successful Response
POST /tickits
1curl -X POST "http://localhost:8000/tickits" \
2 -H "Content-Type: application/json" \
3 -d '{"title":"string","day":"string"}'
1fetch("http://localhost:8000/tickits", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "title": "string",
6 "day": "string"
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/tickits",
5 json={"title":"string","day":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /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.

Handled by api_update_topic
Parameters
board_id string · path
required
topic_id string · path
required
Body · UpdateTopicapplication/json
name string · min length: 1 · max length: 100
start_date string
end_date string
propertyName anything
Responses
200Successful Response
PATCH /boards/example/topics/example
1curl -X PATCH "http://localhost:8000/boards/example/topics/example" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","start_date":"string","end_date":"string"}'
1fetch("http://localhost:8000/boards/example/topics/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "start_date": "string",
7 "end_date": "string"
8}),
9})
10 .then((res) => res.json())
11 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/boards/example/topics/example",
5 json={"name":"string","start_date":"string","end_date":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /boards/:board_id/topics

Add a topic

POST /boards/:board_id/topics: add a topic to a board.

Handled by api_create_topic
Parameters
board_id string · path
required
Body · CreateTopicapplication/json
name string · min length: 1 · max length: 100
required
start_date string
end_date string
propertyName anything
Responses
200Successful Response
POST /boards/example/topics
1curl -X POST "http://localhost:8000/boards/example/topics" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","start_date":"string","end_date":"string"}'
1fetch("http://localhost:8000/boards/example/topics", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "start_date": "string",
7 "end_date": "string"
8}),
9})
10 .then((res) => res.json())
11 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/boards/example/topics",
5 json={"name":"string","start_date":"string","end_date":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
GET /totps/status undocumented

/totps/status

Handled by totp_status
Responses
200Successful Response
GET /totps/status
1curl "http://localhost:8000/totps/status"
1fetch("http://localhost:8000/totps/status")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/totps/status")
4print(response.json())
200 Example Response
No Body
POST /totps undocumented

/totps

Handled by create_totp
Responses
200Successful Response
POST /totps
1curl -X POST "http://localhost:8000/totps"
1fetch("http://localhost:8000/totps", { method: "POST" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.post("http://localhost:8000/totps")
4print(response.json())
200 Example Response
No Body
DELETE /trash undocumented

/trash

Handled by api_empty_trash
Responses
200Successful Response
DELETE /trash
1curl -X DELETE "http://localhost:8000/trash"
1fetch("http://localhost:8000/trash", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/trash")
4print(response.json())
200 Example Response
No Body
GET /trash undocumented

/trash

Handled by api_list_trash
Responses
200Successful Response
GET /trash
1curl "http://localhost:8000/trash"
1fetch("http://localhost:8000/trash")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/trash")
4print(response.json())
200 Example Response
No Body
POST /trash/restorations

Restore from trash

Handled by api_restore_trash
Body · TrashRestoreapplication/json
ids array
required
propertyName anything
Responses
200Successful Response
POST /trash/restorations
1curl -X POST "http://localhost:8000/trash/restorations" \
2 -H "Content-Type: application/json" \
3 -d '{"ids":["string"]}'
1fetch("http://localhost:8000/trash/restorations", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "ids": [
6 "string"
7 ]
8}),
9})
10 .then((res) => res.json())
11 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/trash/restorations",
5 json={"ids":["string"]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
DELETE /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.

Handled by api_archive_product
Parameters
product_id string · path
required
Responses
200Successful Response
DELETE /vendibles/products/example
1curl -X DELETE "http://localhost:8000/vendibles/products/example"
1fetch("http://localhost:8000/vendibles/products/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/vendibles/products/example")
4print(response.json())
200 Example Response
No Body
DELETE /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.

Handled by api_delete_variant
Parameters
product_id string · path
required
variant_id string · path
required
Responses
200Successful Response
DELETE /vendibles/products/example/variants/example
1curl -X DELETE "http://localhost:8000/vendibles/products/example/variants/example"
1fetch("http://localhost:8000/vendibles/products/example/variants/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/vendibles/products/example/variants/example")
4print(response.json())
200 Example Response
No Body
DELETE /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.

Handled by api_delete_collection
Parameters
collection_id string · path
required
Responses
200Successful Response
DELETE /vendibles/collections/example
1curl -X DELETE "http://localhost:8000/vendibles/collections/example"
1fetch("http://localhost:8000/vendibles/collections/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/vendibles/collections/example")
4print(response.json())
200 Example Response
No Body
DELETE /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.

Handled by api_deactivate_location
Parameters
location_id string · path
required
Responses
200Successful Response
DELETE /vendibles/locations/example
1curl -X DELETE "http://localhost:8000/vendibles/locations/example"
1fetch("http://localhost:8000/vendibles/locations/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/vendibles/locations/example")
4print(response.json())
200 Example Response
No Body
DELETE /vendibles/domains/:domain_id undocumented

/vendibles/domains/:domain_id

Handled by api_delete_domain
Parameters
domain_id string · path
required
Responses
200Successful Response
DELETE /vendibles/domains/example
1curl -X DELETE "http://localhost:8000/vendibles/domains/example"
1fetch("http://localhost:8000/vendibles/domains/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/vendibles/domains/example")
4print(response.json())
200 Example Response
No Body
DELETE /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.

Handled by api_delete_storefront_logo
Responses
200Successful Response
DELETE /vendibles/storefront/logo
1curl -X DELETE "http://localhost:8000/vendibles/storefront/logo"
1fetch("http://localhost:8000/vendibles/storefront/logo", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/vendibles/storefront/logo")
4print(response.json())
200 Example Response
No Body
DELETE /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.

Handled by api_delete_product_image
Parameters
product_id string · path
required
image_id string · path
required
Responses
200Successful Response
DELETE /vendibles/products/example/images/example
1curl -X DELETE "http://localhost:8000/vendibles/products/example/images/example"
1fetch("http://localhost:8000/vendibles/products/example/images/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/vendibles/products/example/images/example")
4print(response.json())
200 Example Response
No Body
DELETE /vendibles/collections/:collection_id/image undocumented

/vendibles/collections/:collection_id/image

DELETE /vendibles/collections/:collection_id/image — take it down.

Handled by api_delete_collection_image
Parameters
collection_id string · path
required
Responses
200Successful Response
DELETE /vendibles/collections/example/image
1curl -X DELETE "http://localhost:8000/vendibles/collections/example/image"
1fetch("http://localhost:8000/vendibles/collections/example/image", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/vendibles/collections/example/image")
4print(response.json())
200 Example Response
No Body
GET /vendibles/products undocumented

/vendibles/products

Handled by api_list_products
Responses
200Successful Response
GET /vendibles/products
1curl "http://localhost:8000/vendibles/products"
1fetch("http://localhost:8000/vendibles/products")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/vendibles/products")
4print(response.json())
200 Example Response
No Body
GET /vendibles/products/:product_id undocumented

/vendibles/products/:product_id

Handled by api_get_product
Parameters
product_id string · path
required
Responses
200Successful Response
GET /vendibles/products/example
1curl "http://localhost:8000/vendibles/products/example"
1fetch("http://localhost:8000/vendibles/products/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/vendibles/products/example")
4print(response.json())
200 Example Response
No Body
GET /vendibles/collections undocumented

/vendibles/collections

Handled by api_list_collections
Responses
200Successful Response
GET /vendibles/collections
1curl "http://localhost:8000/vendibles/collections"
1fetch("http://localhost:8000/vendibles/collections")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/vendibles/collections")
4print(response.json())
200 Example Response
No Body
GET /vendibles/collections/:collection_id undocumented

/vendibles/collections/:collection_id

Handled by api_get_collection
Parameters
collection_id string · path
required
Responses
200Successful Response
GET /vendibles/collections/example
1curl "http://localhost:8000/vendibles/collections/example"
1fetch("http://localhost:8000/vendibles/collections/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/vendibles/collections/example")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_location_tree
Responses
200Successful Response
GET /vendibles/locations/tree
1curl "http://localhost:8000/vendibles/locations/tree"
1fetch("http://localhost:8000/vendibles/locations/tree")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/vendibles/locations/tree")
4print(response.json())
200 Example Response
No Body
GET /vendibles/locations undocumented

/vendibles/locations

Handled by api_list_locations
Responses
200Successful Response
GET /vendibles/locations
1curl "http://localhost:8000/vendibles/locations"
1fetch("http://localhost:8000/vendibles/locations")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/vendibles/locations")
4print(response.json())
200 Example Response
No Body
GET /vendibles/stock undocumented

/vendibles/stock

Handled by api_list_stock
Responses
200Successful Response
GET /vendibles/stock
1curl "http://localhost:8000/vendibles/stock"
1fetch("http://localhost:8000/vendibles/stock")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/vendibles/stock")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_export_movements
Responses
200Successful Response
GET /vendibles/exports
1curl "http://localhost:8000/vendibles/exports"
1fetch("http://localhost:8000/vendibles/exports")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/vendibles/exports")
4print(response.json())
200 Example Response
No Body
GET /vendibles/movements undocumented

/vendibles/movements

Handled by api_list_movements
Responses
200Successful Response
GET /vendibles/movements
1curl "http://localhost:8000/vendibles/movements"
1fetch("http://localhost:8000/vendibles/movements")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/vendibles/movements")
4print(response.json())
200 Example Response
No Body
GET /vendibles/orders undocumented

/vendibles/orders

Handled by api_list_orders
Responses
200Successful Response
GET /vendibles/orders
1curl "http://localhost:8000/vendibles/orders"
1fetch("http://localhost:8000/vendibles/orders")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/vendibles/orders")
4print(response.json())
200 Example Response
No Body
GET /vendibles/orders/:order_id undocumented

/vendibles/orders/:order_id

Handled by api_get_order
Parameters
order_id string · path
required
Responses
200Successful Response
GET /vendibles/orders/example
1curl "http://localhost:8000/vendibles/orders/example"
1fetch("http://localhost:8000/vendibles/orders/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/vendibles/orders/example")
4print(response.json())
200 Example Response
No Body
GET /vendibles/domains undocumented

/vendibles/domains

Handled by api_list_domains
Responses
200Successful Response
GET /vendibles/domains
1curl "http://localhost:8000/vendibles/domains"
1fetch("http://localhost:8000/vendibles/domains")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/vendibles/domains")
4print(response.json())
200 Example Response
No Body
PATCH /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).

Handled by api_update_order
Parameters
order_id string · path
required
Body · UpdateOrderapplication/json
status
required
fulfillment object
propertyName anything
Responses
200Successful Response
PATCH /vendibles/orders/example
1curl -X PATCH "http://localhost:8000/vendibles/orders/example" \
2 -H "Content-Type: application/json" \
3 -d '{"status":null,"fulfillment":{"carrier":"string","tracking_ref":"string","note":"string"}}'
1fetch("http://localhost:8000/vendibles/orders/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "status": null,
6 "fulfillment": {
7 "carrier": "string",
8 "tracking_ref": "string",
9 "note": "string"
10 }
11}),
12})
13 .then((res) => res.json())
14 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/vendibles/orders/example",
5 json={"status":null,"fulfillment":{"carrier":"string","tracking_ref":"string","note":"string"}},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /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.

Handled by api_patch_domain
Parameters
domain_id string · path
required
Body · UpdateDomainapplication/json
status
required
propertyName anything
Responses
200Successful Response
PATCH /vendibles/domains/example
1curl -X PATCH "http://localhost:8000/vendibles/domains/example" \
2 -H "Content-Type: application/json" \
3 -d '{"status":null}'
1fetch("http://localhost:8000/vendibles/domains/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "status": null
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/vendibles/domains/example",
5 json={"status":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /vendibles/products

Create a product and its default variant

Handled by api_create_product
Body · CreateProductapplication/json
kind
required
name string · min length: 1 · max length: 200
required
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
Responses
200Successful Response
POST /vendibles/products
1curl -X POST "http://localhost:8000/vendibles/products" \
2 -H "Content-Type: application/json" \
3 -d '{"kind":null,"name":"string","slug":"string","description":"string","options":["string"],"images":["string"],"unit_of_measure":"string","is_stockable":null,"status":null,"show_in_store":null,"seo":{"title":"string","description":"string"},"metadata":{"tax_category":"string","external_code":"string","brand":"string"},"price":1.5,"sku":"string"}'
1fetch("http://localhost:8000/vendibles/products", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "kind": null,
6 "name": "string",
7 "slug": "string",
8 "description": "string",
9 "options": [
10 "string"
11 ],
12 "images": [
13 "string"
14 ],
15 "unit_of_measure": "string",
16 "is_stockable": null,
17 "status": null,
18 "show_in_store": null,
19 "seo": {
20 "title": "string",
21 "description": "string"
22 },
23 "metadata": {
24 "tax_category": "string",
25 "external_code": "string",
26 "brand": "string"
27 },
28 "price": 1.5,
29 "sku": "string"
30}),
31})
32 .then((res) => res.json())
33 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/vendibles/products",
5 json={"kind":null,"name":"string","slug":"string","description":"string","options":["string"],"images":["string"],"unit_of_measure":"string","is_stockable":null,"status":null,"show_in_store":null,"seo":{"title":"string","description":"string"},"metadata":{"tax_category":"string","external_code":"string","brand":"string"},"price":1.5,"sku":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /vendibles/products/:product_id/variants

Add a variant to a product

Handled by api_add_variant
Parameters
product_id string · path
required
Body · CreateVariantapplication/json
option_values
sku string · min length: 1 · max length: 64
barcode string · min length: 1 · max length: 64
price number
required
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
Responses
200Successful Response
POST /vendibles/products/example/variants
1curl -X POST "http://localhost:8000/vendibles/products/example/variants" \
2 -H "Content-Type: application/json" \
3 -d '{"option_values":null,"sku":"string","barcode":"string","price":1.5,"compare_at_price":1.5,"cost_price":1.5,"position":1,"is_default":null,"is_active":null,"metadata":{"weight_grams":1.5,"length_mm":1.5,"width_mm":1.5,"height_mm":1.5,"image_mrn":"string"},"opening_quantity":1.5,"opening_location_id":"string"}'
1fetch("http://localhost:8000/vendibles/products/example/variants", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "option_values": null,
6 "sku": "string",
7 "barcode": "string",
8 "price": 1.5,
9 "compare_at_price": 1.5,
10 "cost_price": 1.5,
11 "position": 1,
12 "is_default": null,
13 "is_active": null,
14 "metadata": {
15 "weight_grams": 1.5,
16 "length_mm": 1.5,
17 "width_mm": 1.5,
18 "height_mm": 1.5,
19 "image_mrn": "string"
20 },
21 "opening_quantity": 1.5,
22 "opening_location_id": "string"
23}),
24})
25 .then((res) => res.json())
26 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/vendibles/products/example/variants",
5 json={"option_values":null,"sku":"string","barcode":"string","price":1.5,"compare_at_price":1.5,"cost_price":1.5,"position":1,"is_default":null,"is_active":null,"metadata":{"weight_grams":1.5,"length_mm":1.5,"width_mm":1.5,"height_mm":1.5,"image_mrn":"string"},"opening_quantity":1.5,"opening_location_id":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /vendibles/collections

Create a merchandising collection

Handled by api_create_collection
Body · CreateCollectionapplication/json
name string · min length: 1 · max length: 200
required
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
Responses
200Successful Response
POST /vendibles/collections
1curl -X POST "http://localhost:8000/vendibles/collections" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","parent_id":"string","slug":"string","description":"string","image_mrn":"string","product_ids":["string"],"position":1,"is_visible":null}'
1fetch("http://localhost:8000/vendibles/collections", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "parent_id": "string",
7 "slug": "string",
8 "description": "string",
9 "image_mrn": "string",
10 "product_ids": [
11 "string"
12 ],
13 "position": 1,
14 "is_visible": null
15}),
16})
17 .then((res) => res.json())
18 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/vendibles/collections",
5 json={"name":"string","parent_id":"string","slug":"string","description":"string","image_mrn":"string","product_ids":["string"],"position":1,"is_visible":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /vendibles/locations

Create a stock location

Handled by api_create_location
Body · CreateLocationapplication/json
name string · min length: 1 · max length: 120
required
timezone string · min length: 1 · max length: 64
required
workdays
work_start string · max length: 5
work_end string · max length: 5
is_default
propertyName anything
Responses
200Successful Response
POST /vendibles/locations
1curl -X POST "http://localhost:8000/vendibles/locations" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","timezone":"string","workdays":null,"work_start":"string","work_end":"string","is_default":null}'
1fetch("http://localhost:8000/vendibles/locations", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "timezone": "string",
7 "workdays": null,
8 "work_start": "string",
9 "work_end": "string",
10 "is_default": null
11}),
12})
13 .then((res) => res.json())
14 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/vendibles/locations",
5 json={"name":"string","timezone":"string","workdays":null,"work_start":"string","work_end":"string","is_default":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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.

Handled by api_create_movement
Body · CreateMovementapplication/json
variant_id string · min length: 1 · max length: 100
required
quantity number
required
reason
required
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
Responses
200Successful Response
POST /vendibles/movements
1curl -X POST "http://localhost:8000/vendibles/movements" \
2 -H "Content-Type: application/json" \
3 -d '{"variant_id":"string","quantity":1.5,"reason":null,"from_location_id":"string","to_location_id":"string","unit_cost":1.5,"reference_mrn":"string","occurred_at":"string","notes":"string"}'
1fetch("http://localhost:8000/vendibles/movements", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "variant_id": "string",
6 "quantity": 1.5,
7 "reason": null,
8 "from_location_id": "string",
9 "to_location_id": "string",
10 "unit_cost": 1.5,
11 "reference_mrn": "string",
12 "occurred_at": "string",
13 "notes": "string"
14}),
15})
16 .then((res) => res.json())
17 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/vendibles/movements",
5 json={"variant_id":"string","quantity":1.5,"reason":null,"from_location_id":"string","to_location_id":"string","unit_cost":1.5,"reference_mrn":"string","occurred_at":"string","notes":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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.

Handled by api_create_transfer
Body · CreateTransferapplication/json
from_location_id string · min length: 1 · max length: 100
required
to_location_id string · min length: 1 · max length: 100
required
lines array
required
occurred_at string · min length: 1 · max length: 60
notes string · max length: 2000
propertyName anything
Responses
200Successful Response
POST /vendibles/transfers
1curl -X POST "http://localhost:8000/vendibles/transfers" \
2 -H "Content-Type: application/json" \
3 -d '{"from_location_id":"string","to_location_id":"string","lines":[{"variant_id":"string","quantity":1.5}],"occurred_at":"string","notes":"string"}'
1fetch("http://localhost:8000/vendibles/transfers", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "from_location_id": "string",
6 "to_location_id": "string",
7 "lines": [
8 {
9 "variant_id": "string",
10 "quantity": 1.5
11 }
12 ],
13 "occurred_at": "string",
14 "notes": "string"
15}),
16})
17 .then((res) => res.json())
18 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/vendibles/transfers",
5 json={"from_location_id":"string","to_location_id":"string","lines":[{"variant_id":"string","quantity":1.5}],"occurred_at":"string","notes":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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.

Handled by api_create_count
Body · CreateCountapplication/json
location_id string · min length: 1 · max length: 100
required
lines array
required
occurred_at string · min length: 1 · max length: 60
notes string · max length: 2000
propertyName anything
Responses
200Successful Response
POST /vendibles/counts
1curl -X POST "http://localhost:8000/vendibles/counts" \
2 -H "Content-Type: application/json" \
3 -d '{"location_id":"string","lines":[{"variant_id":"string","counted":1.5}],"occurred_at":"string","notes":"string"}'
1fetch("http://localhost:8000/vendibles/counts", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "location_id": "string",
6 "lines": [
7 {
8 "variant_id": "string",
9 "counted": 1.5
10 }
11 ],
12 "occurred_at": "string",
13 "notes": "string"
14}),
15})
16 .then((res) => res.json())
17 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/vendibles/counts",
5 json={"location_id":"string","lines":[{"variant_id":"string","counted":1.5}],"occurred_at":"string","notes":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /vendibles/domains

Add a domain to point at the store

Handled by api_create_domain
Body · CreateDomainapplication/json
hostname string · min length: 4 · max length: 253
required
propertyName anything
Responses
200Successful Response
POST /vendibles/domains
1curl -X POST "http://localhost:8000/vendibles/domains" \
2 -H "Content-Type: application/json" \
3 -d '{"hostname":"string"}'
1fetch("http://localhost:8000/vendibles/domains", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "hostname": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/vendibles/domains",
5 json={"hostname":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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.

Handled by api_add_product_image
Parameters
product_id string · path
required
Responses
200Successful Response
POST /vendibles/products/example/images
1curl -X POST "http://localhost:8000/vendibles/products/example/images"
1fetch("http://localhost:8000/vendibles/products/example/images", { method: "POST" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.post("http://localhost:8000/vendibles/products/example/images")
4print(response.json())
200 Example Response
No Body
PUT /vendibles/products/:product_id

Update a product

Handled by api_update_product
Parameters
product_id string · path
required
Body · UpdateProductapplication/json
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
Responses
200Successful Response
PUT /vendibles/products/example
1curl -X PUT "http://localhost:8000/vendibles/products/example" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","slug":"string","description":"string","options":["string"],"images":["string"],"unit_of_measure":"string","is_stockable":null,"status":null,"show_in_store":null,"seo":{"title":"string","description":"string"},"metadata":{"tax_category":"string","external_code":"string","brand":"string"}}'
1fetch("http://localhost:8000/vendibles/products/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "slug": "string",
7 "description": "string",
8 "options": [
9 "string"
10 ],
11 "images": [
12 "string"
13 ],
14 "unit_of_measure": "string",
15 "is_stockable": null,
16 "status": null,
17 "show_in_store": null,
18 "seo": {
19 "title": "string",
20 "description": "string"
21 },
22 "metadata": {
23 "tax_category": "string",
24 "external_code": "string",
25 "brand": "string"
26 }
27}),
28})
29 .then((res) => res.json())
30 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/vendibles/products/example",
5 json={"name":"string","slug":"string","description":"string","options":["string"],"images":["string"],"unit_of_measure":"string","is_stockable":null,"status":null,"show_in_store":null,"seo":{"title":"string","description":"string"},"metadata":{"tax_category":"string","external_code":"string","brand":"string"}},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /vendibles/products/:product_id/variants/:variant_id

Update a variant

Handled by api_update_variant
Parameters
product_id string · path
required
variant_id string · path
required
Body · UpdateVariantapplication/json
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
Responses
200Successful Response
PUT /vendibles/products/example/variants/example
1curl -X PUT "http://localhost:8000/vendibles/products/example/variants/example" \
2 -H "Content-Type: application/json" \
3 -d '{"option_values":null,"sku":"string","barcode":"string","price":1.5,"compare_at_price":1.5,"cost_price":1.5,"position":1,"is_default":null,"is_active":null,"metadata":{"weight_grams":1.5,"length_mm":1.5,"width_mm":1.5,"height_mm":1.5,"image_mrn":"string"}}'
1fetch("http://localhost:8000/vendibles/products/example/variants/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "option_values": null,
6 "sku": "string",
7 "barcode": "string",
8 "price": 1.5,
9 "compare_at_price": 1.5,
10 "cost_price": 1.5,
11 "position": 1,
12 "is_default": null,
13 "is_active": null,
14 "metadata": {
15 "weight_grams": 1.5,
16 "length_mm": 1.5,
17 "width_mm": 1.5,
18 "height_mm": 1.5,
19 "image_mrn": "string"
20 }
21}),
22})
23 .then((res) => res.json())
24 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/vendibles/products/example/variants/example",
5 json={"option_values":null,"sku":"string","barcode":"string","price":1.5,"compare_at_price":1.5,"cost_price":1.5,"position":1,"is_default":null,"is_active":null,"metadata":{"weight_grams":1.5,"length_mm":1.5,"width_mm":1.5,"height_mm":1.5,"image_mrn":"string"}},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /vendibles/collections/:collection_id

Update a collection, including its merchandising order

Handled by api_update_collection
Parameters
collection_id string · path
required
Body · UpdateCollectionapplication/json
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
Responses
200Successful Response
PUT /vendibles/collections/example
1curl -X PUT "http://localhost:8000/vendibles/collections/example" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","parent_id":"string","slug":"string","description":"string","image_mrn":"string","icon":"string","product_ids":["string"],"position":1,"is_visible":null}'
1fetch("http://localhost:8000/vendibles/collections/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "parent_id": "string",
7 "slug": "string",
8 "description": "string",
9 "image_mrn": "string",
10 "icon": "string",
11 "product_ids": [
12 "string"
13 ],
14 "position": 1,
15 "is_visible": null
16}),
17})
18 .then((res) => res.json())
19 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/vendibles/collections/example",
5 json={"name":"string","parent_id":"string","slug":"string","description":"string","image_mrn":"string","icon":"string","product_ids":["string"],"position":1,"is_visible":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /vendibles/locations/:location_id

Update or move a location

Handled by api_update_location
Parameters
location_id string · path
required
Body · UpdateLocationapplication/json
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
Responses
200Successful Response
PUT /vendibles/locations/example
1curl -X PUT "http://localhost:8000/vendibles/locations/example" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","timezone":"string","workdays":null,"work_start":"string","work_end":"string","is_default":null}'
1fetch("http://localhost:8000/vendibles/locations/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "timezone": "string",
7 "workdays": null,
8 "work_start": "string",
9 "work_end": "string",
10 "is_default": null
11}),
12})
13 .then((res) => res.json())
14 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/vendibles/locations/example",
5 json={"name":"string","timezone":"string","workdays":null,"work_start":"string","work_end":"string","is_default":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /vendibles/stock/:stock_id/reorder-point

Set or clear a reorder point

Handled by api_set_reorder_point
Parameters
stock_id string · path
required
Body · SetReorderPointapplication/json
reorder_point number
propertyName anything
Responses
200Successful Response
PUT /vendibles/stock/example/reorder-point
1curl -X PUT "http://localhost:8000/vendibles/stock/example/reorder-point" \
2 -H "Content-Type: application/json" \
3 -d '{"reorder_point":1.5}'
1fetch("http://localhost:8000/vendibles/stock/example/reorder-point", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "reorder_point": 1.5
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/vendibles/stock/example/reorder-point",
5 json={"reorder_point":1.5},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /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.

Handled by api_update_storefront_theme
Body · UpdateStorefrontThemeapplication/json
typeset
button_style
fluid
colors object
propertyName anything
Responses
200Successful Response
PUT /vendibles/storefront/theme
1curl -X PUT "http://localhost:8000/vendibles/storefront/theme" \
2 -H "Content-Type: application/json" \
3 -d '{"typeset":null,"button_style":null,"fluid":null,"colors":{"primary":"string","accent":"string","background":"string","text":"string"}}'
1fetch("http://localhost:8000/vendibles/storefront/theme", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "typeset": null,
6 "button_style": null,
7 "fluid": null,
8 "colors": {
9 "primary": "string",
10 "accent": "string",
11 "background": "string",
12 "text": "string"
13 }
14}),
15})
16 .then((res) => res.json())
17 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/vendibles/storefront/theme",
5 json={"typeset":null,"button_style":null,"fluid":null,"colors":{"primary":"string","accent":"string","background":"string","text":"string"}},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /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.

Handled by api_update_storefront_logo
Responses
200Successful Response
PUT /vendibles/storefront/logo
1curl -X PUT "http://localhost:8000/vendibles/storefront/logo"
1fetch("http://localhost:8000/vendibles/storefront/logo", { method: "PUT" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.put("http://localhost:8000/vendibles/storefront/logo")
4print(response.json())
200 Example Response
No Body
PUT /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.

Handled by api_reorder_product_images
Parameters
product_id string · path
required
Body · ReorderImagesapplication/json
order array
required
propertyName anything
Responses
200Successful Response
PUT /vendibles/products/example/images
1curl -X PUT "http://localhost:8000/vendibles/products/example/images" \
2 -H "Content-Type: application/json" \
3 -d '{"order":["string"]}'
1fetch("http://localhost:8000/vendibles/products/example/images", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "order": [
6 "string"
7 ]
8}),
9})
10 .then((res) => res.json())
11 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/vendibles/products/example/images",
5 json={"order":["string"]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /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.

Handled by api_set_collection_image
Parameters
collection_id string · path
required
Responses
200Successful Response
PUT /vendibles/collections/example/image
1curl -X PUT "http://localhost:8000/vendibles/collections/example/image"
1fetch("http://localhost:8000/vendibles/collections/example/image", { method: "PUT" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.put("http://localhost:8000/vendibles/collections/example/image")
4print(response.json())
200 Example Response
No Body
POST /verifications/resend undocumented

/verifications/resend

Handled by resend_otp
Responses
200Successful Response
POST /verifications/resend
1curl -X POST "http://localhost:8000/verifications/resend"
1fetch("http://localhost:8000/verifications/resend", { method: "POST" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.post("http://localhost:8000/verifications/resend")
4print(response.json())
200 Example Response
No Body
DELETE /views/:view_id undocumented

/views/:view_id

Handled by api_delete_saved_view
Parameters
view_id string · path
required
Responses
200Successful Response
DELETE /views/example
1curl -X DELETE "http://localhost:8000/views/example"
1fetch("http://localhost:8000/views/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/views/example")
4print(response.json())
200 Example Response
No Body
GET /views undocumented

/views

Handled by api_list_saved_views
Responses
200Successful Response
GET /views
1curl "http://localhost:8000/views"
1fetch("http://localhost:8000/views")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/views")
4print(response.json())
200 Example Response
No Body
GET /wands/events undocumented

/wands/events

List all platform events available as flow triggers.

Handled by api_list_events
Responses
200Successful Response
GET /wands/events
1curl "http://localhost:8000/wands/events"
1fetch("http://localhost:8000/wands/events")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/wands/events")
4print(response.json())
200 Example Response
No Body
GET /wands/filters undocumented

/wands/filters

List all registered Jinja2 filters with descriptions.

Handled by api_list_filters
Responses
200Successful Response
GET /wands/filters
1curl "http://localhost:8000/wands/filters"
1fetch("http://localhost:8000/wands/filters")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/wands/filters")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_get_step_context
Parameters
spell_id string · path
required
step_index string · path
required
Responses
200Successful Response
GET /wands/context/example/example
1curl "http://localhost:8000/wands/context/example/example"
1fetch("http://localhost:8000/wands/context/example/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/wands/context/example/example")
4print(response.json())
200 Example Response
No Body
GET /wands/macros undocumented

/wands/macros

All macros. ?grouped=true returns them in category order with Spellbook-rendered examples (what the reference page renders).

Handled by api_list_macros
Responses
200Successful Response
GET /wands/macros
1curl "http://localhost:8000/wands/macros"
1fetch("http://localhost:8000/wands/macros")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/wands/macros")
4print(response.json())
200 Example Response
No Body
GET /wands/macros/:macro_name undocumented

/wands/macros/:macro_name

Handled by api_get_macro
Parameters
macro_name string · path
required
Responses
200Successful Response
GET /wands/macros/example
1curl "http://localhost:8000/wands/macros/example"
1fetch("http://localhost:8000/wands/macros/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/wands/macros/example")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_list_event_samples
Responses
200Successful Response
GET /wands/samples
1curl "http://localhost:8000/wands/samples"
1fetch("http://localhost:8000/wands/samples")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/wands/samples")
4print(response.json())
200 Example Response
No Body
GET /wands/recipes undocumented

/wands/recipes

Curated recipe gallery, filtered to the workspace's installed apps.

Handled by api_list_recipes
Responses
200Successful Response
GET /wands/recipes
1curl "http://localhost:8000/wands/recipes"
1fetch("http://localhost:8000/wands/recipes")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/wands/recipes")
4print(response.json())
200 Example Response
No Body
GET /wands/stats undocumented

/wands/stats

Workspace automation dashboard payload.

Handled by api_wands_stats
Responses
200Successful Response
GET /wands/stats
1curl "http://localhost:8000/wands/stats"
1fetch("http://localhost:8000/wands/stats")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/wands/stats")
4print(response.json())
200 Example Response
No Body
DELETE /wiki/trash undocumented

/wiki/trash

DELETE /wiki/trash: delete for good every trashed page in a space the caller may purge.

Handled by api_empty_trash
Responses
200Successful Response
DELETE /wiki/trash
1curl -X DELETE "http://localhost:8000/wiki/trash"
1fetch("http://localhost:8000/wiki/trash", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/wiki/trash")
4print(response.json())
200 Example Response
No Body
DELETE /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.

Handled by api_delete_trashed_page
Parameters
page_id string · path
required
Responses
200Successful Response
DELETE /wiki/trash/example
1curl -X DELETE "http://localhost:8000/wiki/trash/example"
1fetch("http://localhost:8000/wiki/trash/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/wiki/trash/example")
4print(response.json())
200 Example Response
No Body
DELETE /wiki/spaces/:space_id undocumented

/wiki/spaces/:space_id

DELETE /wiki/spaces/:space_id: remove an empty space. General cannot be removed.

Handled by api_delete_space
Parameters
space_id string · path
required
Responses
200Successful Response
DELETE /wiki/spaces/example
1curl -X DELETE "http://localhost:8000/wiki/spaces/example"
1fetch("http://localhost:8000/wiki/spaces/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/wiki/spaces/example")
4print(response.json())
200 Example Response
No Body
GET /wiki/tree undocumented

/wiki/tree

GET /wiki/tree — get the full page tree for the workspace.

Handled by api_get_tree
Responses
200Successful Response
GET /wiki/tree
1curl "http://localhost:8000/wiki/tree"
1fetch("http://localhost:8000/wiki/tree")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/wiki/tree")
4print(response.json())
200 Example Response
No Body
GET /wiki/trash undocumented

/wiki/trash

GET /wiki/trash: pages in the trash the caller may restore or delete for good.

Handled by api_list_trash
Responses
200Successful Response
GET /wiki/trash
1curl "http://localhost:8000/wiki/trash"
1fetch("http://localhost:8000/wiki/trash")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/wiki/trash")
4print(response.json())
200 Example Response
No Body
GET /wiki/share-roles undocumented

/wiki/share-roles

GET /wiki/share-roles — roles a member may add to a page share list.

Handled by api_list_share_roles
Responses
200Successful Response
GET /wiki/share-roles
1curl "http://localhost:8000/wiki/share-roles"
1fetch("http://localhost:8000/wiki/share-roles")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/wiki/share-roles")
4print(response.json())
200 Example Response
No Body
GET /wiki/spaces undocumented

/wiki/spaces

GET /wiki/spaces: every space in the workspace, General first.

Handled by api_list_spaces
Responses
200Successful Response
GET /wiki/spaces
1curl "http://localhost:8000/wiki/spaces"
1fetch("http://localhost:8000/wiki/spaces")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/wiki/spaces")
4print(response.json())
200 Example Response
No Body
GET /wiki/spaces/:space_id undocumented

/wiki/spaces/:space_id

GET /wiki/spaces/:space_id: one space.

Handled by api_get_space
Parameters
space_id string · path
required
Responses
200Successful Response
GET /wiki/spaces/example
1curl "http://localhost:8000/wiki/spaces/example"
1fetch("http://localhost:8000/wiki/spaces/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/wiki/spaces/example")
4print(response.json())
200 Example Response
No Body
PATCH /wikis/:page_id

Update a wiki page

PATCH /wikis/:page_id — update page title, content, icon, etc.

Handled by api_update_page
Parameters
page_id string · path
required
Body · UpdatePageapplication/json
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
Responses
200Successful Response
PATCH /wikis/example
1curl -X PATCH "http://localhost:8000/wikis/example" \
2 -H "Content-Type: application/json" \
3 -d '{"deleted":null,"title":"string","icon":"string","icon_type":null,"content":"string","position":1,"parent_id":"string","cover":"string","status":null,"reviewers":["string"],"target_date":"string","team":"string","properties":[{"key":"string","label":"string","value":"string"}],"tags":["string"],"kind":null,"columns":[{"key":"string","label":"string","type":null,"options":[{"value":"string","label":"string","tone":null}]}]}'
1fetch("http://localhost:8000/wikis/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "deleted": null,
6 "title": "string",
7 "icon": "string",
8 "icon_type": null,
9 "content": "string",
10 "position": 1,
11 "parent_id": "string",
12 "cover": "string",
13 "status": null,
14 "reviewers": [
15 "string"
16 ],
17 "target_date": "string",
18 "team": "string",
19 "properties": [
20 {
21 "key": "string",
22 "label": "string",
23 "value": "string"
24 }
25 ],
26 "tags": [
27 "string"
28 ],
29 "kind": null,
30 "columns": [
31 {
32 "key": "string",
33 "label": "string",
34 "type": null,
35 "options": [
36 {
37 "value": "string",
38 "label": "string",
39 "tone": null
40 }
41 ]
42 }
43 ]
44}),
45})
46 .then((res) => res.json())
47 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/wikis/example",
5 json={"deleted":null,"title":"string","icon":"string","icon_type":null,"content":"string","position":1,"parent_id":"string","cover":"string","status":null,"reviewers":["string"],"target_date":"string","team":"string","properties":[{"key":"string","label":"string","value":"string"}],"tags":["string"],"kind":null,"columns":[{"key":"string","label":"string","type":null,"options":[{"value":"string","label":"string","tone":null}]}]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /wiki/spaces/:space_id

Update a wiki space

PATCH /wiki/spaces/:space_id: rename, describe or reorder a space.

Handled by api_update_space
Parameters
space_id string · path
required
Body · UpdateSpaceapplication/json
name string · min length: 1 · max length: 120
description string · max length: 500
position integer · min: 0
propertyName anything
Responses
200Successful Response
PATCH /wiki/spaces/example
1curl -X PATCH "http://localhost:8000/wiki/spaces/example" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","description":"string","position":1}'
1fetch("http://localhost:8000/wiki/spaces/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "description": "string",
7 "position": 1
8}),
9})
10 .then((res) => res.json())
11 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/wiki/spaces/example",
5 json={"name":"string","description":"string","position":1},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /wikis/:page_id/comments/:comment_id

Resolve/unresolve comment

PATCH /wikis/:page_id/comments/:comment_id — resolve or unresolve.

Handled by api_resolve_comment
Parameters
page_id string · path
required
comment_id string · path
required
Body · ResolveCommentapplication/json
resolved
required
propertyName anything
Responses
200Successful Response
PATCH /wikis/example/comments/example
1curl -X PATCH "http://localhost:8000/wikis/example/comments/example" \
2 -H "Content-Type: application/json" \
3 -d '{"resolved":null}'
1fetch("http://localhost:8000/wikis/example/comments/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "resolved": null
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/wikis/example/comments/example",
5 json={"resolved":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /wikis/:page_id/subscription

Star or watch a page

PATCH /wikis/:page_id/subscription: the caller's own star and watch on the page.

Handled by api_update_subscription
Parameters
page_id string · path
required
Body · UpdateSubscriptionapplication/json
starred
watching
propertyName anything
Responses
200Successful Response
PATCH /wikis/example/subscription
1curl -X PATCH "http://localhost:8000/wikis/example/subscription" \
2 -H "Content-Type: application/json" \
3 -d '{"starred":null,"watching":null}'
1fetch("http://localhost:8000/wikis/example/subscription", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "starred": null,
6 "watching": null
7}),
8})
9 .then((res) => res.json())
10 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/wikis/example/subscription",
5 json={"starred":null,"watching":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /wikis/:page_id/rows/:row_id

Update a database row

PATCH /wikis/:page_id/rows/:row_id: change cells or reorder a row.

Handled by api_update_row
Parameters
page_id string · path
required
row_id string · path
required
Body · UpdateRowapplication/json
cells array
position integer · min: 0
propertyName anything
Responses
200Successful Response
PATCH /wikis/example/rows/example
1curl -X PATCH "http://localhost:8000/wikis/example/rows/example" \
2 -H "Content-Type: application/json" \
3 -d '{"cells":[{"key":"string","value":"string"}],"position":1}'
1fetch("http://localhost:8000/wikis/example/rows/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "cells": [
6 {
7 "key": "string",
8 "value": "string"
9 }
10 ],
11 "position": 1
12}),
13})
14 .then((res) => res.json())
15 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/wikis/example/rows/example",
5 json={"cells":[{"key":"string","value":"string"}],"position":1},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /wikis

Create a wiki page

POST /wikis — create a new wiki page.

Handled by api_create_page
Body · CreatePageapplication/json
title string · min length: 1 · max length: 500
required
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
Responses
200Successful Response
POST /wikis
1curl -X POST "http://localhost:8000/wikis" \
2 -H "Content-Type: application/json" \
3 -d '{"title":"string","parent_id":"string","space_id":"string","kind":null,"icon":"string","icon_type":null,"content":"string","template_id":"string"}'
1fetch("http://localhost:8000/wikis", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "title": "string",
6 "parent_id": "string",
7 "space_id": "string",
8 "kind": null,
9 "icon": "string",
10 "icon_type": null,
11 "content": "string",
12 "template_id": "string"
13}),
14})
15 .then((res) => res.json())
16 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/wikis",
5 json={"title":"string","parent_id":"string","space_id":"string","kind":null,"icon":"string","icon_type":null,"content":"string","template_id":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /wiki/spaces

Create a wiki space

POST /wiki/spaces: a new team space.

Handled by api_create_space
Body · CreateSpaceapplication/json
name string · min length: 1 · max length: 120
required
description string · max length: 500
kind
propertyName anything
Responses
200Successful Response
POST /wiki/spaces
1curl -X POST "http://localhost:8000/wiki/spaces" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string","description":"string","kind":null}'
1fetch("http://localhost:8000/wiki/spaces", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string",
6 "description": "string",
7 "kind": null
8}),
9})
10 .then((res) => res.json())
11 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/wiki/spaces",
5 json={"name":"string","description":"string","kind":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /wikis/:page_id/comments

Add a comment

POST /wikis/:page_id/comments — add a comment.

Handled by api_create_comment
Parameters
page_id string · path
required
Body · CreateCommentapplication/json
body string · min length: 1 · max length: 4000
required
object_id string · max length: 64
parent_id string · max length: 64
nx number
ny number
propertyName anything
Responses
200Successful Response
POST /wikis/example/comments
1curl -X POST "http://localhost:8000/wikis/example/comments" \
2 -H "Content-Type: application/json" \
3 -d '{"body":"string","object_id":"string","parent_id":"string","nx":1.5,"ny":1.5}'
1fetch("http://localhost:8000/wikis/example/comments", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "body": "string",
6 "object_id": "string",
7 "parent_id": "string",
8 "nx": 1.5,
9 "ny": 1.5
10}),
11})
12 .then((res) => res.json())
13 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/wikis/example/comments",
5 json={"body":"string","object_id":"string","parent_id":"string","nx":1.5,"ny":1.5},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /wikis/:page_id/reactions

Like a page

POST /wikis/:page_id/reactions: the caller likes the page. Liking twice is one like.

Handled by api_create_reaction
Parameters
page_id string · path
required
Body · CreateReactionapplication/json
kind
required
propertyName anything
Responses
200Successful Response
POST /wikis/example/reactions
1curl -X POST "http://localhost:8000/wikis/example/reactions" \
2 -H "Content-Type: application/json" \
3 -d '{"kind":null}'
1fetch("http://localhost:8000/wikis/example/reactions", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "kind": null
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/wikis/example/reactions",
5 json={"kind":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /wikis/:page_id/rows

Add a database row

POST /wikis/:page_id/rows: a new row at the end of a database page.

Handled by api_create_row
Parameters
page_id string · path
required
Body · CreateRowapplication/json
cells array
position integer · min: 0
propertyName anything
Responses
200Successful Response
POST /wikis/example/rows
1curl -X POST "http://localhost:8000/wikis/example/rows" \
2 -H "Content-Type: application/json" \
3 -d '{"cells":[{"key":"string","value":"string"}],"position":1}'
1fetch("http://localhost:8000/wikis/example/rows", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "cells": [
6 {
7 "key": "string",
8 "value": "string"
9 }
10 ],
11 "position": 1
12}),
13})
14 .then((res) => res.json())
15 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/wikis/example/rows",
5 json={"cells":[{"key":"string","value":"string"}],"position":1},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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.

Handled by api_create_page_media
Parameters
page_id string · path
required
Body · CreatePageMediaapplication/json
key string · min length: 1 · max length: 1024
required
filename string · max length: 255
content_type string · max length: 100
size_bytes integer · min: 0
propertyName anything
Responses
200Successful Response
POST /wikis/example/media
1curl -X POST "http://localhost:8000/wikis/example/media" \
2 -H "Content-Type: application/json" \
3 -d '{"key":"string","filename":"string","content_type":"string","size_bytes":1}'
1fetch("http://localhost:8000/wikis/example/media", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "key": "string",
6 "filename": "string",
7 "content_type": "string",
8 "size_bytes": 1
9}),
10})
11 .then((res) => res.json())
12 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/wikis/example/media",
5 json={"key":"string","filename":"string","content_type":"string","size_bytes":1},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /wikis/:page_id/position

Move/reorder a page

PUT /wikis/:page_id/position — move a page to a new parent/position.

Handled by api_move_page
Parameters
page_id string · path
required
Body · MovePageapplication/json
parent_id string
position integer · min: 0
required
space_id string · max length: 100
propertyName anything
Responses
200Successful Response
PUT /wikis/example/position
1curl -X PUT "http://localhost:8000/wikis/example/position" \
2 -H "Content-Type: application/json" \
3 -d '{"parent_id":"string","position":1,"space_id":"string"}'
1fetch("http://localhost:8000/wikis/example/position", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "parent_id": "string",
6 "position": 1,
7 "space_id": "string"
8}),
9})
10 .then((res) => res.json())
11 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/wikis/example/position",
5 json={"parent_id":"string","position":1,"space_id":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /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).

Handled by api_update_page_access
Parameters
page_id string · path
required
Body · UpdatePageAccessapplication/json
visibility
required
shares array
required
propertyName anything
Responses
200Successful Response
PUT /wikis/example/access
1curl -X PUT "http://localhost:8000/wikis/example/access" \
2 -H "Content-Type: application/json" \
3 -d '{"visibility":null,"shares":[{"type":null,"id":"string","level":null}]}'
1fetch("http://localhost:8000/wikis/example/access", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "visibility": null,
6 "shares": [
7 {
8 "type": null,
9 "id": "string",
10 "level": null
11 }
12 ]
13}),
14})
15 .then((res) => res.json())
16 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/wikis/example/access",
5 json={"visibility":null,"shares":[{"type":null,"id":"string","level":null}]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /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.

Handled by api_set_page_publication
Parameters
page_id string · path
required
Body · UpdatePagePublicationapplication/json
is_published
required
propertyName anything
Responses
200Successful Response
PUT /wikis/example/publication
1curl -X PUT "http://localhost:8000/wikis/example/publication" \
2 -H "Content-Type: application/json" \
3 -d '{"is_published":null}'
1fetch("http://localhost:8000/wikis/example/publication", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "is_published": null
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/wikis/example/publication",
5 json={"is_published":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
DELETE /wikis/:page_id undocumented

/wikis/:page_id

DELETE /wikis/:page_id — soft-delete a page and its descendants.

Handled by api_delete_page
Parameters
page_id string · path
required
Responses
200Successful Response
DELETE /wikis/example
1curl -X DELETE "http://localhost:8000/wikis/example"
1fetch("http://localhost:8000/wikis/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/wikis/example")
4print(response.json())
200 Example Response
No Body
DELETE /wikis/:page_id/comments/:comment_id undocumented

/wikis/:page_id/comments/:comment_id

DELETE /wikis/:page_id/comments/:comment_id — delete a comment.

Handled by api_delete_comment
Parameters
page_id string · path
required
comment_id string · path
required
Responses
200Successful Response
DELETE /wikis/example/comments/example
1curl -X DELETE "http://localhost:8000/wikis/example/comments/example"
1fetch("http://localhost:8000/wikis/example/comments/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/wikis/example/comments/example")
4print(response.json())
200 Example Response
No Body
DELETE /wikis/:page_id/reactions/:kind undocumented

/wikis/:page_id/reactions/:kind

DELETE /wikis/:page_id/reactions/:kind: the caller takes their like back.

Handled by api_delete_reaction
Parameters
page_id string · path
required
kind string · path
required
Responses
200Successful Response
DELETE /wikis/example/reactions/example
1curl -X DELETE "http://localhost:8000/wikis/example/reactions/example"
1fetch("http://localhost:8000/wikis/example/reactions/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/wikis/example/reactions/example")
4print(response.json())
200 Example Response
No Body
DELETE /wikis/:page_id/rows/:row_id undocumented

/wikis/:page_id/rows/:row_id

DELETE /wikis/:page_id/rows/:row_id: remove a row.

Handled by api_delete_row
Parameters
page_id string · path
required
row_id string · path
required
Responses
200Successful Response
DELETE /wikis/example/rows/example
1curl -X DELETE "http://localhost:8000/wikis/example/rows/example"
1fetch("http://localhost:8000/wikis/example/rows/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/wikis/example/rows/example")
4print(response.json())
200 Example Response
No Body
DELETE /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.

Handled by api_delete_page_media
Parameters
page_id string · path
required
media_id string · path
required
Responses
200Successful Response
DELETE /wikis/example/media/example
1curl -X DELETE "http://localhost:8000/wikis/example/media/example"
1fetch("http://localhost:8000/wikis/example/media/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/wikis/example/media/example")
4print(response.json())
200 Example Response
No Body
GET /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).

Handled by api_list_pages
Responses
200Successful Response
GET /wikis
1curl "http://localhost:8000/wikis"
1fetch("http://localhost:8000/wikis")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/wikis")
4print(response.json())
200 Example Response
No Body
GET /wikis/:page_id undocumented

/wikis/:page_id

GET /wikis/:page_id — get a single page with content.

Handled by api_get_page
Parameters
page_id string · path
required
Responses
200Successful Response
GET /wikis/example
1curl "http://localhost:8000/wikis/example"
1fetch("http://localhost:8000/wikis/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/wikis/example")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_list_children
Parameters
page_id string · path
required
Responses
200Successful Response
GET /wikis/example/children
1curl "http://localhost:8000/wikis/example/children"
1fetch("http://localhost:8000/wikis/example/children")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/wikis/example/children")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_list_backlinks
Parameters
page_id string · path
required
Responses
200Successful Response
GET /wikis/example/backlinks
1curl "http://localhost:8000/wikis/example/backlinks"
1fetch("http://localhost:8000/wikis/example/backlinks")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/wikis/example/backlinks")
4print(response.json())
200 Example Response
No Body
GET /wikis/:page_id/versions undocumented

/wikis/:page_id/versions

GET /wikis/:page_id/versions — list version history.

Handled by api_list_versions
Parameters
page_id string · path
required
Responses
200Successful Response
GET /wikis/example/versions
1curl "http://localhost:8000/wikis/example/versions"
1fetch("http://localhost:8000/wikis/example/versions")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/wikis/example/versions")
4print(response.json())
200 Example Response
No Body
GET /wikis/:page_id/versions/:version_id undocumented

/wikis/:page_id/versions/:version_id

GET /wikis/:page_id/versions/:version_id — get a single version.

Handled by api_get_version
Parameters
page_id string · path
required
version_id string · path
required
Responses
200Successful Response
GET /wikis/example/versions/example
1curl "http://localhost:8000/wikis/example/versions/example"
1fetch("http://localhost:8000/wikis/example/versions/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/wikis/example/versions/example")
4print(response.json())
200 Example Response
No Body
GET /wikis/:page_id/comments undocumented

/wikis/:page_id/comments

GET /wikis/:page_id/comments — list comments for a page.

Handled by api_list_comments
Parameters
page_id string · path
required
Responses
200Successful Response
GET /wikis/example/comments
1curl "http://localhost:8000/wikis/example/comments"
1fetch("http://localhost:8000/wikis/example/comments")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/wikis/example/comments")
4print(response.json())
200 Example Response
No Body
GET /wikis/:page_id/presence undocumented

/wikis/:page_id/presence

GET /wikis/:page_id/presence — get active collaborators.

Handled by api_get_presence
Parameters
page_id string · path
required
Responses
200Successful Response
GET /wikis/example/presence
1curl "http://localhost:8000/wikis/example/presence"
1fetch("http://localhost:8000/wikis/example/presence")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/wikis/example/presence")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_list_rows
Parameters
page_id string · path
required
Responses
200Successful Response
GET /wikis/example/rows
1curl "http://localhost:8000/wikis/example/rows"
1fetch("http://localhost:8000/wikis/example/rows")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/wikis/example/rows")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_get_page_media
Parameters
page_id string · path
required
media_id string · path
required
Responses
200Successful Response
GET /wikis/example/media/example
1curl "http://localhost:8000/wikis/example/media/example"
1fetch("http://localhost:8000/wikis/example/media/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/wikis/example/media/example")
4print(response.json())
200 Example Response
No Body
POST /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.

Handled by api_create_view
Parameters
page_id string · path
required
Responses
200Successful Response
POST /wikis/example/views
1curl -X POST "http://localhost:8000/wikis/example/views"
1fetch("http://localhost:8000/wikis/example/views", { method: "POST" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.post("http://localhost:8000/wikis/example/views")
4print(response.json())
200 Example Response
No Body
PUT /wikis/:page_id/presence undocumented

/wikis/:page_id/presence

PUT /wikis/:page_id/presence — update cursor position.

Handled by api_update_presence
Parameters
page_id string · path
required
Responses
200Successful Response
PUT /wikis/example/presence
1curl -X PUT "http://localhost:8000/wikis/example/presence"
1fetch("http://localhost:8000/wikis/example/presence", { method: "PUT" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.put("http://localhost:8000/wikis/example/presence")
4print(response.json())
200 Example Response
No Body
PATCH /workers/:worker_id/documents/:document_id

Move or rename a worker document

Move a document between folders (and to/from root), or rename it.

Handled by api_update_document
Parameters
worker_id string · path
required
document_id string · path
required
Body · UpdateDocumentapplication/json
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
Responses
200Successful Response
PATCH /workers/example/documents/example
1curl -X PATCH "http://localhost:8000/workers/example/documents/example" \
2 -H "Content-Type: application/json" \
3 -d '{"title":"string","icon":"string","icon_type":null,"content":"string","is_starred":null,"page_mode":null,"visibility":null,"page_setup":{"size":null,"orientation":null,"margins":null,"margin_x":1,"margin_y":1,"header_text":"string","footer_text":"string","show_page_numbers":null,"watermark_text":"string"},"deleted":null}'
1fetch("http://localhost:8000/workers/example/documents/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "title": "string",
6 "icon": "string",
7 "icon_type": null,
8 "content": "string",
9 "is_starred": null,
10 "page_mode": null,
11 "visibility": null,
12 "page_setup": {
13 "size": null,
14 "orientation": null,
15 "margins": null,
16 "margin_x": 1,
17 "margin_y": 1,
18 "header_text": "string",
19 "footer_text": "string",
20 "show_page_numbers": null,
21 "watermark_text": "string"
22 },
23 "deleted": null
24}),
25})
26 .then((res) => res.json())
27 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/workers/example/documents/example",
5 json={"title":"string","icon":"string","icon_type":null,"content":"string","is_starred":null,"page_mode":null,"visibility":null,"page_setup":{"size":null,"orientation":null,"margins":null,"margin_x":1,"margin_y":1,"header_text":"string","footer_text":"string","show_page_numbers":null,"watermark_text":"string"},"deleted":null},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /workers/:worker_id/documents/folders

Create a document folder

Handled by api_create_folder
Parameters
worker_id string · path
required
Body · CreateDocumentFolderapplication/json
name string · min length: 1 · max length: 120
required
propertyName anything
Responses
200Successful Response
POST /workers/example/documents/folders
1curl -X POST "http://localhost:8000/workers/example/documents/folders" \
2 -H "Content-Type: application/json" \
3 -d '{"name":"string"}'
1fetch("http://localhost:8000/workers/example/documents/folders", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "name": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/workers/example/documents/folders",
5 json={"name":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /workers/:worker_id/documents

Record an uploaded worker document

Record a document the browser already uploaded to R2 (Computer source).

Handled by api_create_document
Parameters
worker_id string · path
required
Body · CreateDocumentapplication/json
title string · min length: 1 · max length: 500
required
icon string · max length: 100
icon_type
content string
propertyName anything
Responses
200Successful Response
POST /workers/example/documents
1curl -X POST "http://localhost:8000/workers/example/documents" \
2 -H "Content-Type: application/json" \
3 -d '{"title":"string","icon":"string","icon_type":null,"content":"string"}'
1fetch("http://localhost:8000/workers/example/documents", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "title": "string",
6 "icon": "string",
7 "icon_type": null,
8 "content": "string"
9}),
10})
11 .then((res) => res.json())
12 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/workers/example/documents",
5 json={"title":"string","icon":"string","icon_type":null,"content":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /workers/:worker_id/notes

Add a note to a worker

Handled by api_create_worker_note
Parameters
worker_id string · path
required
Body · CreateWorkerNoteapplication/json
text string · min length: 1 · max length: 5000
required
propertyName anything
Responses
200Successful Response
POST /workers/example/notes
1curl -X POST "http://localhost:8000/workers/example/notes" \
2 -H "Content-Type: application/json" \
3 -d '{"text":"string"}'
1fetch("http://localhost:8000/workers/example/notes", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "text": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/workers/example/notes",
5 json={"text":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /workers/:worker_id/notes/:note_id

Update a worker note

Handled by api_update_worker_note
Parameters
worker_id string · path
required
note_id string · path
required
Body · UpdateWorkerNoteapplication/json
text string · min length: 1 · max length: 5000
required
propertyName anything
Responses
200Successful Response
PUT /workers/example/notes/example
1curl -X PUT "http://localhost:8000/workers/example/notes/example" \
2 -H "Content-Type: application/json" \
3 -d '{"text":"string"}'
1fetch("http://localhost:8000/workers/example/notes/example", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "text": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/workers/example/notes/example",
5 json={"text":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /workers/:worker_id/personal

Update personal details

PATCH personal details — merge provided keys; empty string clears a key.

Handled by api_update_personal
Parameters
worker_id string · path
required
Body · UpdateWorkerPersonalapplication/json
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
Responses
200Successful Response
PATCH /workers/example/personal
1curl -X PATCH "http://localhost:8000/workers/example/personal" \
2 -H "Content-Type: application/json" \
3 -d '{"date_of_birth":"string","gender":"string","pronouns":"string","nationality":"string","marital_status":"string","personal_email":"string","personal_phone":"string","address_line1":"string","address_line2":"string","city":"string","state":"string","postal_code":"string","country":"string"}'
1fetch("http://localhost:8000/workers/example/personal", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "date_of_birth": "string",
6 "gender": "string",
7 "pronouns": "string",
8 "nationality": "string",
9 "marital_status": "string",
10 "personal_email": "string",
11 "personal_phone": "string",
12 "address_line1": "string",
13 "address_line2": "string",
14 "city": "string",
15 "state": "string",
16 "postal_code": "string",
17 "country": "string"
18}),
19})
20 .then((res) => res.json())
21 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/workers/example/personal",
5 json={"date_of_birth":"string","gender":"string","pronouns":"string","nationality":"string","marital_status":"string","personal_email":"string","personal_phone":"string","address_line1":"string","address_line2":"string","city":"string","state":"string","postal_code":"string","country":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /workers/:worker_id/qualifications

Update qualifications

PATCH qualifications — each provided collection replaces that collection.

Handled by api_update_qualifications
Parameters
worker_id string · path
required
Body · UpdateQualificationsapplication/json
education array
certifications array
skills array
languages array
propertyName anything
Responses
200Successful Response
PATCH /workers/example/qualifications
1curl -X PATCH "http://localhost:8000/workers/example/qualifications" \
2 -H "Content-Type: application/json" \
3 -d '{"education":[{"institution":"string","id":"string","degree":"string","field_of_study":"string","start_year":1,"end_year":1}],"certifications":[{"name":"string","id":"string","issuer":"string","issued_date":"string","expiry_date":"string","credential_id":"string"}],"skills":["string"],"languages":[{"language":"string","id":"string","proficiency":null}]}'
1fetch("http://localhost:8000/workers/example/qualifications", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "education": [
6 {
7 "institution": "string",
8 "id": "string",
9 "degree": "string",
10 "field_of_study": "string",
11 "start_year": 1,
12 "end_year": 1
13 }
14 ],
15 "certifications": [
16 {
17 "name": "string",
18 "id": "string",
19 "issuer": "string",
20 "issued_date": "string",
21 "expiry_date": "string",
22 "credential_id": "string"
23 }
24 ],
25 "skills": [
26 "string"
27 ],
28 "languages": [
29 {
30 "language": "string",
31 "id": "string",
32 "proficiency": null
33 }
34 ]
35}),
36})
37 .then((res) => res.json())
38 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/workers/example/qualifications",
5 json={"education":[{"institution":"string","id":"string","degree":"string","field_of_study":"string","start_year":1,"end_year":1}],"certifications":[{"name":"string","id":"string","issuer":"string","issued_date":"string","expiry_date":"string","credential_id":"string"}],"skills":["string"],"languages":[{"language":"string","id":"string","proficiency":null}]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PATCH /workers/:worker_id/bank-details

Update bank details

PATCH bank details — merge flat fields; identifiers list replaces whole.

Handled by api_update_bank_details
Parameters
worker_id string · path
required
Body · UpdateBankDetailsapplication/json
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
Responses
200Successful Response
PATCH /workers/example/bank-details
1curl -X PATCH "http://localhost:8000/workers/example/bank-details" \
2 -H "Content-Type: application/json" \
3 -d '{"bank_name":"string","account_name":"string","account_number":"string","branch_code":"string","iban":"string","swift_bic":"string","currency":"string","notes":"string","identifiers":[{"kind":null,"value":"string","id":"string","label":"string"}]}'
1fetch("http://localhost:8000/workers/example/bank-details", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "bank_name": "string",
6 "account_name": "string",
7 "account_number": "string",
8 "branch_code": "string",
9 "iban": "string",
10 "swift_bic": "string",
11 "currency": "string",
12 "notes": "string",
13 "identifiers": [
14 {
15 "kind": null,
16 "value": "string",
17 "id": "string",
18 "label": "string"
19 }
20 ]
21}),
22})
23 .then((res) => res.json())
24 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/workers/example/bank-details",
5 json={"bank_name":"string","account_name":"string","account_number":"string","branch_code":"string","iban":"string","swift_bic":"string","currency":"string","notes":"string","identifiers":[{"kind":null,"value":"string","id":"string","label":"string"}]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /workers/:worker_id/emergency-contacts

Replace emergency contacts

PUT the full emergency contacts list (replace semantics).

Handled by api_update_emergency_contacts
Parameters
worker_id string · path
required
Body · UpdateEmergencyContactsapplication/json
contacts array
required
propertyName anything
Responses
200Successful Response
PUT /workers/example/emergency-contacts
1curl -X PUT "http://localhost:8000/workers/example/emergency-contacts" \
2 -H "Content-Type: application/json" \
3 -d '{"contacts":[{"name":"string","id":"string","relationship":"string","phone":"string","email":"string","is_primary":null}]}'
1fetch("http://localhost:8000/workers/example/emergency-contacts", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "contacts": [
6 {
7 "name": "string",
8 "id": "string",
9 "relationship": "string",
10 "phone": "string",
11 "email": "string",
12 "is_primary": null
13 }
14 ]
15}),
16})
17 .then((res) => res.json())
18 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/workers/example/emergency-contacts",
5 json={"contacts":[{"name":"string","id":"string","relationship":"string","phone":"string","email":"string","is_primary":null}]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
PUT /workers/:worker_id/right-to-work

Replace right-to-work documents

PUT the full right-to-work document list (replace semantics).

Handled by api_update_right_to_work
Parameters
worker_id string · path
required
Body · UpdateRightToWorkapplication/json
records array
required
propertyName anything
Responses
200Successful Response
PUT /workers/example/right-to-work
1curl -X PUT "http://localhost:8000/workers/example/right-to-work" \
2 -H "Content-Type: application/json" \
3 -d '{"records":[{"document_type":null,"id":"string","country":"string","number":"string","issued_date":"string","expiry_date":"string","notes":"string"}]}'
1fetch("http://localhost:8000/workers/example/right-to-work", {
2 method: "PUT",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "records": [
6 {
7 "document_type": null,
8 "id": "string",
9 "country": "string",
10 "number": "string",
11 "issued_date": "string",
12 "expiry_date": "string",
13 "notes": "string"
14 }
15 ]
16}),
17})
18 .then((res) => res.json())
19 .then(console.log);
1import requests
2
3response = requests.put(
4 "http://localhost:8000/workers/example/right-to-work",
5 json={"records":[{"document_type":null,"id":"string","country":"string","number":"string","issued_date":"string","expiry_date":"string","notes":"string"}]},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
DELETE /workers/:worker_id undocumented

/workers/:worker_id

Handled by api_delete_worker
Parameters
worker_id string · path
required
Responses
200Successful Response
DELETE /workers/example
1curl -X DELETE "http://localhost:8000/workers/example"
1fetch("http://localhost:8000/workers/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/workers/example")
4print(response.json())
200 Example Response
No Body
DELETE /workers/fields/:field_id undocumented

/workers/fields/:field_id

Handled by api_delete_field_definition
Parameters
field_id string · path
required
Responses
200Successful Response
DELETE /workers/fields/example
1curl -X DELETE "http://localhost:8000/workers/fields/example"
1fetch("http://localhost:8000/workers/fields/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/workers/fields/example")
4print(response.json())
200 Example Response
No Body
DELETE /workers/:worker_id/notes/:note_id undocumented

/workers/:worker_id/notes/:note_id

Handled by api_delete_worker_note
Parameters
worker_id string · path
required
note_id string · path
required
Responses
200Successful Response
DELETE /workers/example/notes/example
1curl -X DELETE "http://localhost:8000/workers/example/notes/example"
1fetch("http://localhost:8000/workers/example/notes/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/workers/example/notes/example")
4print(response.json())
200 Example Response
No Body
DELETE /workers/:worker_id/employment/:record_id undocumented

/workers/:worker_id/employment/:record_id

Handled by api_delete_employment
Parameters
worker_id string · path
required
record_id string · path
required
Responses
200Successful Response
DELETE /workers/example/employment/example
1curl -X DELETE "http://localhost:8000/workers/example/employment/example"
1fetch("http://localhost:8000/workers/example/employment/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/workers/example/employment/example")
4print(response.json())
200 Example Response
No Body
DELETE /workers/:worker_id/documents/folders/:folder_id undocumented

/workers/:worker_id/documents/folders/:folder_id

Handled by api_delete_folder
Parameters
worker_id string · path
required
folder_id string · path
required
Responses
200Successful Response
DELETE /workers/example/documents/folders/example
1curl -X DELETE "http://localhost:8000/workers/example/documents/folders/example"
1fetch("http://localhost:8000/workers/example/documents/folders/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/workers/example/documents/folders/example")
4print(response.json())
200 Example Response
No Body
DELETE /workers/:worker_id/documents/:document_id undocumented

/workers/:worker_id/documents/:document_id

Handled by api_delete_document
Parameters
worker_id string · path
required
document_id string · path
required
Responses
200Successful Response
DELETE /workers/example/documents/example
1curl -X DELETE "http://localhost:8000/workers/example/documents/example"
1fetch("http://localhost:8000/workers/example/documents/example", { method: "DELETE" })
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.delete("http://localhost:8000/workers/example/documents/example")
4print(response.json())
200 Example Response
No Body
GET /workers undocumented

/workers

Handled by api_list_workers
Responses
200Successful Response
GET /workers
1curl "http://localhost:8000/workers"
1fetch("http://localhost:8000/workers")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/workers")
4print(response.json())
200 Example Response
No Body
GET /workers/:worker_id undocumented

/workers/:worker_id

Handled by api_get_worker
Parameters
worker_id string · path
required
Responses
200Successful Response
GET /workers/example
1curl "http://localhost:8000/workers/example"
1fetch("http://localhost:8000/workers/example")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/workers/example")
4print(response.json())
200 Example Response
No Body
GET /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.

Handled by api_get_routes
Parameters
worker_id string · path
required
Responses
200Successful Response
GET /workers/example/routes
1curl "http://localhost:8000/workers/example/routes"
1fetch("http://localhost:8000/workers/example/routes")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/workers/example/routes")
4print(response.json())
200 Example Response
No Body
GET /workers/locations/:location_id/members undocumented

/workers/locations/:location_id/members

Workers currently assigned to a location — powers the delete dialog count.

Handled by api_list_location_members
Parameters
location_id string · path
required
Responses
200Successful Response
GET /workers/locations/example/members
1curl "http://localhost:8000/workers/locations/example/members"
1fetch("http://localhost:8000/workers/locations/example/members")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/workers/locations/example/members")
4print(response.json())
200 Example Response
No Body
GET /workers/fields undocumented

/workers/fields

Handled by api_list_field_definitions
Responses
200Successful Response
GET /workers/fields
1curl "http://localhost:8000/workers/fields"
1fetch("http://localhost:8000/workers/fields")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/workers/fields")
4print(response.json())
200 Example Response
No Body
GET /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.*.

Handled by api_get_worker_fields
Parameters
worker_id string · path
required
Responses
200Successful Response
GET /workers/example/fields
1curl "http://localhost:8000/workers/example/fields"
1fetch("http://localhost:8000/workers/example/fields")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/workers/example/fields")
4print(response.json())
200 Example Response
No Body
GET /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.*).

Handled by api_get_personal
Parameters
worker_id string · path
required
Responses
200Successful Response
GET /workers/example/personal
1curl "http://localhost:8000/workers/example/personal"
1fetch("http://localhost:8000/workers/example/personal")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/workers/example/personal")
4print(response.json())
200 Example Response
No Body
GET /workers/:worker_id/bank-details undocumented

/workers/:worker_id/bank-details

Bank details + identity numbers (gated on workers.sensitive.*).

Handled by api_get_bank_details
Parameters
worker_id string · path
required
Responses
200Successful Response
GET /workers/example/bank-details
1curl "http://localhost:8000/workers/example/bank-details"
1fetch("http://localhost:8000/workers/example/bank-details")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/workers/example/bank-details")
4print(response.json())
200 Example Response
No Body
GET /workers/:worker_id/notes undocumented

/workers/:worker_id/notes

Handled by api_list_worker_notes
Parameters
worker_id string · path
required
Responses
200Successful Response
GET /workers/example/notes
1curl "http://localhost:8000/workers/example/notes"
1fetch("http://localhost:8000/workers/example/notes")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/workers/example/notes")
4print(response.json())
200 Example Response
No Body
GET /workers/:worker_id/compensation undocumented

/workers/:worker_id/compensation

Handled by api_list_compensation
Parameters
worker_id string · path
required
Responses
200Successful Response
GET /workers/example/compensation
1curl "http://localhost:8000/workers/example/compensation"
1fetch("http://localhost:8000/workers/example/compensation")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/workers/example/compensation")
4print(response.json())
200 Example Response
No Body
GET /workers/:worker_id/employment undocumented

/workers/:worker_id/employment

Handled by api_list_employment
Parameters
worker_id string · path
required
Responses
200Successful Response
GET /workers/example/employment
1curl "http://localhost:8000/workers/example/employment"
1fetch("http://localhost:8000/workers/example/employment")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/workers/example/employment")
4print(response.json())
200 Example Response
No Body
GET /workers/:worker_id/documents undocumented

/workers/:worker_id/documents

Handled by api_list_documents
Parameters
worker_id string · path
required
Responses
200Successful Response
GET /workers/example/documents
1curl "http://localhost:8000/workers/example/documents"
1fetch("http://localhost:8000/workers/example/documents")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/workers/example/documents")
4print(response.json())
200 Example Response
No Body
GET /workers/:worker_id/documents/:document_id/view undocumented

/workers/:worker_id/documents/:document_id/view

Short-lived presigned GET URL for a worker document.

Handled by api_view_document
Parameters
worker_id string · path
required
document_id string · path
required
Responses
200Successful Response
GET /workers/example/documents/example/view
1curl "http://localhost:8000/workers/example/documents/example/view"
1fetch("http://localhost:8000/workers/example/documents/example/view")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/workers/example/documents/example/view")
4print(response.json())
200 Example Response
No Body
PATCH /workers/:worker_id

Update a worker profile

Handled by api_update_worker
Parameters
worker_id string · path
required
Body · UpdateWorkerapplication/json
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
Responses
200Successful Response
PATCH /workers/example
1curl -X PATCH "http://localhost:8000/workers/example" \
2 -H "Content-Type: application/json" \
3 -d '{"full_name":"string","employee_id":"string","department_id":"string","manager_id":"string","status":null,"location_mrn":"string","work_location":"string","work_mode":null,"expected_hours_per_day":1.5,"work_email":"string","work_phone":"string","notes":"string"}'
1fetch("http://localhost:8000/workers/example", {
2 method: "PATCH",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "full_name": "string",
6 "employee_id": "string",
7 "department_id": "string",
8 "manager_id": "string",
9 "status": null,
10 "location_mrn": "string",
11 "work_location": "string",
12 "work_mode": null,
13 "expected_hours_per_day": 1.5,
14 "work_email": "string",
15 "work_phone": "string",
16 "notes": "string"
17}),
18})
19 .then((res) => res.json())
20 .then(console.log);
1import requests
2
3response = requests.patch(
4 "http://localhost:8000/workers/example",
5 json={"full_name":"string","employee_id":"string","department_id":"string","manager_id":"string","status":null,"location_mrn":"string","work_location":"string","work_mode":null,"expected_hours_per_day":1.5,"work_email":"string","work_phone":"string","notes":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /workers

Create a worker profile

Handled by api_create_worker
Body · CreateWorkerapplication/json
member_mrn string · min length: 1
required
full_name string · max length: 200
job_title string · min length: 1 · max length: 200
required
hire_date string · min length: 1
required
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
Responses
200Successful Response
POST /workers
1curl -X POST "http://localhost:8000/workers" \
2 -H "Content-Type: application/json" \
3 -d '{"member_mrn":"string","full_name":"string","job_title":"string","hire_date":"string","employee_id":"string","department_id":"string","manager_id":"string","employment_type":null,"status":null,"location_mrn":"string","work_location":"string","work_mode":null,"expected_hours_per_day":1.5,"work_email":"string","work_phone":"string","notes":"string"}'
1fetch("http://localhost:8000/workers", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "member_mrn": "string",
6 "full_name": "string",
7 "job_title": "string",
8 "hire_date": "string",
9 "employee_id": "string",
10 "department_id": "string",
11 "manager_id": "string",
12 "employment_type": null,
13 "status": null,
14 "location_mrn": "string",
15 "work_location": "string",
16 "work_mode": null,
17 "expected_hours_per_day": 1.5,
18 "work_email": "string",
19 "work_phone": "string",
20 "notes": "string"
21}),
22})
23 .then((res) => res.json())
24 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/workers",
5 json={"member_mrn":"string","full_name":"string","job_title":"string","hire_date":"string","employee_id":"string","department_id":"string","manager_id":"string","employment_type":null,"status":null,"location_mrn":"string","work_location":"string","work_mode":null,"expected_hours_per_day":1.5,"work_email":"string","work_phone":"string","notes":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
POST /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.

Handled by api_reassign_location
Parameters
location_id string · path
required
Body · ReassignLocationapplication/json
target string
propertyName anything
Responses
200Successful Response
POST /workers/locations/example/reassignment
1curl -X POST "http://localhost:8000/workers/locations/example/reassignment" \
2 -H "Content-Type: application/json" \
3 -d '{"target":"string"}'
1fetch("http://localhost:8000/workers/locations/example/reassignment", {
2 method: "POST",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "target": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.post(
4 "http://localhost:8000/workers/locations/example/reassignment",
5 json={"target":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
DELETE /workspaces/:id

Delete workspace

DELETE /workspaces/:id: lock the workspace and delete it permanently after the hold. Owner only.

Handled by api_delete_workspace
Parameters
id string · path
required
Body · DeleteWorkspaceapplication/json
confirmation string · min length: 1
required
propertyName anything
Responses
200Successful Response
DELETE /workspaces/example
1curl -X DELETE "http://localhost:8000/workspaces/example" \
2 -H "Content-Type: application/json" \
3 -d '{"confirmation":"string"}'
1fetch("http://localhost:8000/workspaces/example", {
2 method: "DELETE",
3 headers: { "Content-Type": "application/json" },
4 body: JSON.stringify({
5 "confirmation": "string"
6}),
7})
8 .then((res) => res.json())
9 .then(console.log);
1import requests
2
3response = requests.delete(
4 "http://localhost:8000/workspaces/example",
5 json={"confirmation":"string"},
6)
7print(response.json())
Editable: Test Request sends exactly what's here
200 Example Response
No Body
GET /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.

Handled by api_current_workspace
Responses
200Successful Response
GET /workspaces/current
1curl "http://localhost:8000/workspaces/current"
1fetch("http://localhost:8000/workspaces/current")
2 .then((res) => res.json())
3 .then(console.log);
1import requests
2
3response = requests.get("http://localhost:8000/workspaces/current")
4print(response.json())
200 Example Response
No Body
WS/ws

/ws

Platform WebSocket handler — authenticates via session and holds connection open.

Handled by ws_platform
Subdomain api
Connect
1const socket = new WebSocket("ws://localhost:8000/ws");
2
3socket.onopen = () => socket.send("hello");
4socket.onmessage = (event) => console.log(event.data);
Connection Log
Not connected
WS/calls/ws

/calls/ws

WebSocket handler for call signaling and state updates.

Handled by ws_calls
Subdomain api
Connect
1const socket = new WebSocket("ws://localhost:8000/calls/ws");
2
3socket.onopen = () => socket.send("hello");
4socket.onmessage = (event) => console.log(event.data);
Connection Log
Not connected