Slateo API
MCP docs

Slateo API

REST API for the Slateo platform — account-member level access to your projects, tasks, customers, and more.

Get started Authentication

Slateo API (1.0.0)

Download OpenAPI specification:

REST API for the Slateo platform (excludes admin and client routes)

Overview

Overview

The Slateo API is account-member level: every request acts as a specific member of a specific Slateo account, scoped to that member's role and permissions -- the same rules that apply inside the Slateo app itself.

This reference covers what an authenticated member can do: projects, tasks, documents, customers, and the rest of the account's data. It does not cover account creation, cross-account listing, or the web app's own login flow -- those aren't reachable with an API key.

New here? Start with Quickstart. For how requests are authenticated, see Authentication.

Quickstart

Quickstart

  1. Get an API key -- available from Slateo app settings. Session auth only; an API key can't be used to create another API key.

  2. Make a request -- every endpoint is under /api and needs an Authorization: Bearer <api-key> header:

    curl https://app.slateo.io/api/users/me \
      -H "Authorization: Bearer slateo_..."
    
  3. Explore the reference -- endpoints are grouped by resource in the sidebar (Tasks, Projects, Customers, ...). See Authentication for details on scoping and permissions.

Authentication

Authentication

Requests are authenticated with a Slateo API key, sent as a bearer token:

Authorization: Bearer slateo_...
  • Getting a key -- available from Slateo app settings.
  • Scope -- a key acts as the member who created it. It can only see and modify data within that member's account, subject to their role and permissions -- there's no separate account-level or organization-level credential.
  • Also accepted by -- the MCP server, using the same header.

Users

Get the currently authenticated user

Authorizations:
apiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Accounts

Get an account by ID

Authorizations:
apiKeyAuth
path Parameters
accountId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update an account

Authorizations:
apiKeyAuth
path Parameters
accountId
required
string <uuid>
Request Body schema: application/json
name
string
website_url
string
client_type
string (AccountClientType)
Enum: "app" "restora" "site_management" "plantops" "venueops"

Which product surface this account belongs to. Drives which system automations get lazily seeded (e.g. delivery-verification automations only seed for restora/site_management/plantops/venueops).

color
string
logo_url
string
timezone
string
currency
string

ISO 4217 currency code used as the account's default currency.

object

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "website_url": "string",
  • "client_type": "app",
  • "color": "string",
  • "logo_url": "string",
  • "timezone": "string",
  • "currency": "string",
  • "preferences": {
    }
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Delete an account

Hard-deletes the account immediately if it has no tasks, documents, products, customers, deals, or invoices. Otherwise soft-deletes it and schedules a hard delete (cascading all account data) 90 days later. Requires the account.delete permission (OWNER role only).

Authorizations:
apiKeyAuth
path Parameters
accountId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Initiate a subscription payment

Authorizations:
apiKeyAuth
path Parameters
accountId
required
string <uuid>
Request Body schema: application/json
object

Responses

Request samples

Content type
application/json
{ }

Verify subscription payment

Authorizations:
apiKeyAuth
path Parameters
accountId
required
string <uuid>
Request Body schema: application/json
object

Responses

Request samples

Content type
application/json
{ }

Get a presigned upload URL for a file

Authorizations:
apiKeyAuth
path Parameters
accountId
required
string <uuid>
fileName
required
string
query Parameters
resource_type
string or null
Enum: "task" "member" "comment" "product" "project" "bill" "bill_payment" "delivery" "delivery_line_item" "purchase_order" "purchase_requisition" "vendor" "material" "invoice" "deal" "customer"
resource_id
string
resource_field
string
mime_type
string
Default: "application/octet-stream"
size
integer >= 0
Default: 0

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

List attachments for an account

When filtering by resource_type=project together with resource_id, the result also includes attachments on that project's tasks and on comments made on those tasks, in addition to attachments on the project itself.

Authorizations:
apiKeyAuth
path Parameters
accountId
required
string <uuid>
query Parameters
filter
string

key operator value filter convention (see GET /customers for the general syntax). Supported keys: resource_type, resource_id, status, uploaded_by_member_id, id.

sort_by
string
Default: "created_at"
Enum: "created_at" "size" "file_name" "status"
sort_order
string
Default: "desc"
Enum: "asc" "desc"

Responses

Update an attachment

When status is set to completed for an attachment with resource_type=delivery_line_item, and the account has preferences.delivery_photo_verification.enabled, the photo's EXIF GPS is checked against the line item's location and the result is stored under metadata.location_verification (gps, distance_meters, verified).

Authorizations:
apiKeyAuth
path Parameters
accountId
required
string <uuid>
attachmentId
required
string <uuid>
Request Body schema: application/json
object

Responses

Request samples

Content type
application/json
{ }

Onboarding

Mark onboarding as complete

Authorizations:
apiKeyAuth
path Parameters
accountId
required
string <uuid>

Responses

Skip onboarding

Authorizations:
apiKeyAuth
path Parameters
accountId
required
string <uuid>

Responses

Members

List all members

Authorizations:
apiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Create / invite a member

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
email
string <email>
role_id
string <uuid>
display_name
string
job_title
string
timezone
string

IANA timezone (e.g. "America/Los_Angeles") reported by the creating device.

Responses

Request samples

Content type
application/json
{
  • "email": "user@example.com",
  • "role_id": "ac4e70c8-d5be-48af-93eb-760f58fc91a9",
  • "display_name": "string",
  • "job_title": "string",
  • "timezone": "string"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get a member by ID

Authorizations:
apiKeyAuth
path Parameters
memberId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update a member

Authorizations:
apiKeyAuth
path Parameters
memberId
required
string <uuid>
Request Body schema: application/json
display_name
string
avatar_url
string
job_title
string
color
string
timezone
string
preferences
object

Responses

Request samples

Content type
application/json
{
  • "display_name": "string",
  • "avatar_url": "string",
  • "job_title": "string",
  • "color": "string",
  • "timezone": "string",
  • "preferences": { }
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Remove a member

Authorizations:
apiKeyAuth
path Parameters
memberId
required
string <uuid>

Responses

Get notifications for a member

Authorizations:
apiKeyAuth
path Parameters
memberId
required
string <uuid>

Responses

Get timestamp of most recent notification update

Authorizations:
apiKeyAuth
path Parameters
memberId
required
string <uuid>

Responses

Get unread notification count

Authorizations:
apiKeyAuth
path Parameters
memberId
required
string <uuid>

Responses

Mark notifications as read

Authorizations:
apiKeyAuth
path Parameters
memberId
required
string <uuid>

Responses

Register a push notification token

Authorizations:
apiKeyAuth
path Parameters
memberId
required
string <uuid>
Request Body schema: application/json
required
token
required
string
platform
string
Enum: "ios" "android" "web"

Responses

Request samples

Content type
application/json
{
  • "token": "string",
  • "platform": "ios"
}

Memberships

List memberships

Authorizations:
apiKeyAuth
query Parameters
scope_type
string (MembershipScopeType)
Enum: "project" "product" "workstream" "document"
scope_id
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Add a membership

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
member_id
required
string <uuid>
role_id
string <uuid>
scope_type
required
string (MembershipScopeType)
Enum: "project" "product" "workstream" "document"
scope_id
required
string <uuid>
workstream_access_type
string
Enum: "all" "selected"

Responses

Request samples

Content type
application/json
{
  • "member_id": "435a4844-006a-4cfc-a644-e8eb2dd2ca43",
  • "role_id": "ac4e70c8-d5be-48af-93eb-760f58fc91a9",
  • "scope_type": "project",
  • "scope_id": "5d3fe357-12dd-4f62-b004-6d1fb3b8454f",
  • "workstream_access_type": "all"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update a membership

Authorizations:
apiKeyAuth
path Parameters
membershipId
required
string <uuid>
Request Body schema: application/json
role_id
string <uuid>
workstream_access_type
string
Enum: "all" "selected"

Responses

Request samples

Content type
application/json
{
  • "role_id": "ac4e70c8-d5be-48af-93eb-760f58fc91a9",
  • "workstream_access_type": "all"
}

Remove a membership

Authorizations:
apiKeyAuth
path Parameters
membershipId
required
string <uuid>

Responses

Roles

List roles

Authorizations:
apiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Create a role

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
name
required
string
description
string
scope_type
required
string (RoleScopeType)
Enum: "account" "project" "product"
type
string (RoleType)
Enum: "internal" "external"
color
string

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "description": "string",
  • "scope_type": "account",
  • "type": "internal",
  • "color": "string"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get a role by ID

Authorizations:
apiKeyAuth
path Parameters
accountRoleId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update a role

Authorizations:
apiKeyAuth
path Parameters
accountRoleId
required
string <uuid>
Request Body schema: application/json
name
string
description
string
color
string

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "description": "string",
  • "color": "string"
}

Delete a role

Authorizations:
apiKeyAuth
path Parameters
accountRoleId
required
string <uuid>

Responses

Projects

List projects

Authorizations:
apiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Create a project

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
name
required
string
color
string
visibility
string
Enum: "account" "members"
preferences
object
location_id
string or null <uuid>

Must refer to a location owned by this account.

enabled_cycle_categories
Array of strings
Items Enum: "phase" "release" "sprint" "milestone"
Array of objects

Additional existing account members to add to the newly created project

Array of objects

Custom project-scoped roles to create alongside the project. Role names matching a default role (ADMIN, MEMBER, GUEST) are ignored.

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "color": "string",
  • "visibility": "account",
  • "preferences": { },
  • "location_id": "46910cc3-ab41-4b80-b4a7-94dab9f1b795",
  • "enabled_cycle_categories": [
    ],
  • "members": [
    ],
  • "roles": [
    ]
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get a project

Authorizations:
apiKeyAuth
path Parameters
projectId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update a project

Authorizations:
apiKeyAuth
path Parameters
projectId
required
string <uuid>
Request Body schema: application/json
name
string
visibility
string
Enum: "account" "members"
preferences
object
location_id
string or null <uuid>

Must refer to a location owned by this account.

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "visibility": "account",
  • "preferences": { },
  • "location_id": "46910cc3-ab41-4b80-b4a7-94dab9f1b795"
}

Delete a project

Authorizations:
apiKeyAuth
path Parameters
projectId
required
string <uuid>

Responses

Check whether a project can be hard deleted

Authorizations:
apiKeyAuth
path Parameters
projectId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get dashboard data for a project

Authorizations:
apiKeyAuth
path Parameters
projectId
required
string <uuid>

Responses

Get permissions for a project

Authorizations:
apiKeyAuth
path Parameters
projectId
required
string <uuid>

Responses

Set (or clear) the project's current phase, release, or sprint

Authorizations:
apiKeyAuth
path Parameters
projectId
required
string <uuid>
Request Body schema: application/json
required
category
required
string
Enum: "phase" "release" "sprint"
project_cycle_id
required
string or null <uuid>

The project cycle to mark as current for this category, or null to clear it.

Responses

Request samples

Content type
application/json
{
  • "category": "phase",
  • "project_cycle_id": "a7f1ef39-8229-4259-be51-bc431d04a93e"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Workstreams

List workstreams

Authorizations:
apiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Create a workstream

Creates a new Entity (type "workstream") and a Workstream pointing to it, in one call. There is no way to attach a Workstream to an already-existing Entity.

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
project_id
required
string <uuid>
name
required
string
description
string or null
required
object

Responses

Request samples

Content type
application/json
{
  • "project_id": "405d8375-3514-403b-8c43-83ae74cfe0e9",
  • "name": "string",
  • "description": "string",
  • "workflow_template": {
    }
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update a workstream

Authorizations:
apiKeyAuth
path Parameters
workstreamId
required
string <uuid>
Request Body schema: application/json
object

Responses

Request samples

Content type
application/json
{ }

Response samples

Content type
application/json
{
  • "data": {
    }
}

Delete a workstream

Authorizations:
apiKeyAuth
path Parameters
workstreamId
required
string <uuid>

Responses

Get activity logs for a workstream

Authorizations:
apiKeyAuth
path Parameters
workstreamId
required
string <uuid>

Responses

Get activity snapshot since a given time

Authorizations:
apiKeyAuth
path Parameters
workstreamId
required
string <uuid>
query Parameters
since
string <date-time>

Responses

List participation types for a workstream

Authorizations:
apiKeyAuth
path Parameters
workstreamId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Add a participation type to a workstream

Authorizations:
apiKeyAuth
path Parameters
workstreamId
required
string <uuid>
Request Body schema: application/json
required
name
required
string
description
string

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "description": "string"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update a participation type

Authorizations:
apiKeyAuth
path Parameters
workstreamId
required
string <uuid>
typeId
required
string <uuid>
Request Body schema: application/json
name
string
description
string

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "description": "string"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Delete a participation type

Authorizations:
apiKeyAuth
path Parameters
workstreamId
required
string <uuid>
typeId
required
string <uuid>

Responses

Tasks

List tasks

Authorizations:
apiKeyAuth
query Parameters
project_id
string <uuid>
workstream_id
string <uuid>
assigned_to_member_id
string <uuid>
participant_member_id
string <uuid>

Matches tasks where the given member_id is a task_user_participant (in addition to, not instead of, assigned_to_member_id).

priority
string (TaskPriority)
Enum: "high" "medium" "low"
type
string (TaskType)
Enum: "bundle" "task" "subtask"
project_cycle_id
string

A ProjectCycle id, or one of the special tokens current_sprint, current_release, current_phase — each resolves to the project's current cycle of that category, as set via PATCH /projects/{projectId}/current-cycle. Using a token requires a project_id filter to also be set — it's resolved per project.

milestone_id
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Create a task

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
title
required
string
description
string
type
string (TaskType)
Enum: "bundle" "task" "subtask"
priority
string (TaskPriority)
Enum: "high" "medium" "low"
project_id
required
string <uuid>
entity_id
required
string <uuid>
assigned_to_member_id
string <uuid>
parent_id
string or null <uuid>
project_cycle_id
string or null <uuid>
milestone_id
string or null <uuid>
feature_id
string or null <uuid>
due_at
string <date-time>
roadmap_item_id
string <uuid>
source_id
string
source_type
string
source_metadata
object
Array of objects (RequirementDocument)
Array of objects (CustomFieldValueInput)

Responses

Request samples

Content type
application/json
{
  • "title": "string",
  • "description": "string",
  • "type": "bundle",
  • "priority": "high",
  • "project_id": "405d8375-3514-403b-8c43-83ae74cfe0e9",
  • "entity_id": "8161163a-f227-466f-bc01-090a01e80165",
  • "assigned_to_member_id": "f762546b-4e22-4cbc-845d-0a241ae61391",
  • "parent_id": "1c6ca187-e61f-4301-8dcb-0e9749e89eef",
  • "project_cycle_id": "a7f1ef39-8229-4259-be51-bc431d04a93e",
  • "milestone_id": "09ca5787-2524-40b3-af3c-ff5db9ab83d2",
  • "feature_id": "ba6c7b2c-38fc-4a78-a187-51c7bbbd5c50",
  • "due_at": "2019-08-24T14:15:22Z",
  • "roadmap_item_id": "6c886391-cd90-4135-a4b4-24f0dbf94111",
  • "source_id": "string",
  • "source_type": "string",
  • "source_metadata": { },
  • "requirement_documents": [
    ],
  • "custom_fields": [
    ]
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Bulk create tasks

context (source_id/source_type/source_metadata) applies to every task in the batch — unlike POST /tasks, per-task source_id/source_type/source_metadata and custom_fields aren't supported here.

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
Array of objects
object

Applied to every task in the batch.

Responses

Request samples

Content type
application/json
{
  • "tasks": [
    ],
  • "context": {
    }
}

Bulk update tasks

Applies the same field updates to every task in task_ids. Each task is processed independently — permission (task.update, scoped per task's project) and update errors are per-task and don't block the rest of the batch. The response is an array with one entry per requested task, in order, reporting per-task success or failure.

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
task_ids
required
Array of strings <uuid> [ items <uuid > ]
title
string
description
string or null
type
string (TaskType)
Enum: "bundle" "task" "subtask"
priority
string (TaskPriority)
Enum: "high" "medium" "low"
assigned_to_member_id
string or null <uuid>
due_at
string or null <date-time>
resolved_at
string or null <date-time>
project_cycle_id
string or null <uuid>
milestone_id
string or null <uuid>
roadmap_item_id
string or null
feature_id
string or null
parent_id
string or null

Responses

Request samples

Content type
application/json
{
  • "task_ids": [
    ],
  • "title": "string",
  • "description": "string",
  • "type": "bundle",
  • "priority": "high",
  • "assigned_to_member_id": "f762546b-4e22-4cbc-845d-0a241ae61391",
  • "due_at": "2019-08-24T14:15:22Z",
  • "resolved_at": "2019-08-24T14:15:22Z",
  • "project_cycle_id": "a7f1ef39-8229-4259-be51-bc431d04a93e",
  • "milestone_id": "09ca5787-2524-40b3-af3c-ff5db9ab83d2",
  • "roadmap_item_id": "string",
  • "feature_id": "string",
  • "parent_id": "string"
}

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Bulk update the workflow stage of tasks

Moves every task in task_ids to workflow_template_stage_id. Each task is processed independently through the same stage-condition and approval checks as POST /tasks/{taskId}/workflow_stages (see that endpoint's description) — one task's failure (missing permission, unmet conditions, unmet approvals) does not block or roll back the others. The response is an array with one entry per requested task, in order, reporting per-task success or failure.

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
task_ids
required
Array of strings <uuid> [ items <uuid > ]
workflow_template_stage_id
required
string <uuid>
planned_start_at
string <date-time>
planned_end_at
string <date-time>
actual_start_at
string <date-time>
start_event_note
string

Free-text note attached to the newly-entered stage's start event, if the target stage has one configured.

end_event_note
string

Free-text note attached to the previous stage's end event, if it has one configured.

bypass_approvals
boolean

Requires the task.stage.bypass_approval permission (checked per task's project). When true, unmet required approvals are logged on the task's activity log instead of blocking the move.

Responses

Request samples

Content type
application/json
{
  • "task_ids": [
    ],
  • "workflow_template_stage_id": "79ea45b2-4be3-4980-a12d-3fd314348625",
  • "planned_start_at": "2019-08-24T14:15:22Z",
  • "planned_end_at": "2019-08-24T14:15:22Z",
  • "actual_start_at": "2019-08-24T14:15:22Z",
  • "start_event_note": "string",
  • "end_event_note": "string",
  • "bypass_approvals": true
}

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Get a task

Authorizations:
apiKeyAuth
path Parameters
taskId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update a task

Authorizations:
apiKeyAuth
path Parameters
taskId
required
string <uuid>
Request Body schema: application/json
title
string
description
string
priority
string (TaskPriority)
Enum: "high" "medium" "low"
assigned_to_member_id
string <uuid>
due_at
string <date-time>
project_cycle_id
string or null <uuid>
milestone_id
string or null <uuid>
feature_id
string or null <uuid>

Responses

Request samples

Content type
application/json
{
  • "title": "string",
  • "description": "string",
  • "priority": "high",
  • "assigned_to_member_id": "f762546b-4e22-4cbc-845d-0a241ae61391",
  • "due_at": "2019-08-24T14:15:22Z",
  • "project_cycle_id": "a7f1ef39-8229-4259-be51-bc431d04a93e",
  • "milestone_id": "09ca5787-2524-40b3-af3c-ff5db9ab83d2",
  • "feature_id": "ba6c7b2c-38fc-4a78-a187-51c7bbbd5c50"
}

Delete a task

Authorizations:
apiKeyAuth
path Parameters
taskId
required
string <uuid>

Responses

List comments on a task

Authorizations:
apiKeyAuth
path Parameters
taskId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Add a comment to a task

Authorizations:
apiKeyAuth
path Parameters
taskId
required
string <uuid>
Request Body schema: application/json
required
content
required
string

Responses

Request samples

Content type
application/json
{
  • "content": "string"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Add labels to a task

Authorizations:
apiKeyAuth
path Parameters
taskId
required
string <uuid>
Request Body schema: application/json
required
label_ids
required
Array of strings <uuid> [ items <uuid > ]

Responses

Request samples

Content type
application/json
{
  • "label_ids": [
    ]
}

Remove a label from a task

Authorizations:
apiKeyAuth
path Parameters
taskId
required
string <uuid>
labelId
required
string <uuid>

Responses

Update the workflow stage of a task

Moves the task to workflow_template_stage_id. Before the move is applied, the backend:

  1. Evaluates any stage-entry conditions configured on the target stage (see /entity-workflow-templates/{workflowTemplateId}/entity-workflow-template-stages/{workflowTemplateStageId}/conditions). If any condition fails, responds 422 with the list of failures — this check cannot be bypassed.
  2. Checks whether the target stage has required approvers configured (see the .../approvers endpoint) and whether they've all approved (see GET .../workflow_stages/{stageId}/approvals). If approvals are missing, responds 422 unless bypass_approvals: true is sent — bypassing requires the task.stage.bypass_approval permission, otherwise responds 403.
Authorizations:
apiKeyAuth
path Parameters
taskId
required
string <uuid>
Request Body schema: application/json
required
workflow_template_stage_id
required
string <uuid>
planned_start_at
string <date-time>
planned_end_at
string <date-time>
actual_start_at
string <date-time>
start_event_note
string

Free-text note attached to the newly-entered stage's start event, if the target stage has one configured.

end_event_note
string

Free-text note attached to the previous stage's end event, if it has one configured.

bypass_approvals
boolean

Requires the task.stage.bypass_approval permission. When true, unmet required approvals are logged on the task's activity log instead of blocking the move.

Responses

Request samples

Content type
application/json
{
  • "workflow_template_stage_id": "79ea45b2-4be3-4980-a12d-3fd314348625",
  • "planned_start_at": "2019-08-24T14:15:22Z",
  • "planned_end_at": "2019-08-24T14:15:22Z",
  • "actual_start_at": "2019-08-24T14:15:22Z",
  • "start_event_note": "string",
  • "end_event_note": "string",
  • "bypass_approvals": true
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get approval status for a task's stage

Returns one entry per participation type required to approve entry into this stage, whether it's satisfied, and by whom.

Authorizations:
apiKeyAuth
path Parameters
taskId
required
string <uuid>
stageId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Approve a task's entry into a stage

Records approval on behalf of entity_user_participation_type_id. The approving member must hold that participation type on this task (via the task's participants) and the participation type must be configured as a required approver for the stage, otherwise 403/400.

Authorizations:
apiKeyAuth
path Parameters
taskId
required
string <uuid>
stageId
required
string <uuid>
Request Body schema: application/json
required
entity_user_participation_type_id
required
string <uuid>
comment
string or null

Responses

Request samples

Content type
application/json
{
  • "entity_user_participation_type_id": "23f2e07a-d7b4-45d9-8d71-31226db54e3f",
  • "comment": "string"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Revoke a stage approval

Authorizations:
apiKeyAuth
path Parameters
taskId
required
string <uuid>
stageId
required
string <uuid>
approvalId
required
string <uuid>

Responses

Check whether a task is eligible to move into a stage

Read-only dry run of the two checks POST .../workflow_stages performs before moving a task: stage-entry conditions (evaluateConditions) and required-approver satisfaction (getApprovalStatus). Does not move the task or record anything. eligible is true only when both stage_conditions.passed is true and every entry in approvals is satisfied. Note that bypass_approvals (available on the actual move endpoint) is not reflected here — this reports the unbypassed eligibility.

Authorizations:
apiKeyAuth
path Parameters
taskId
required
string <uuid>
stageId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get activity logs for a task

Authorizations:
apiKeyAuth
path Parameters
taskId
required
string <uuid>

Responses

Get last activity time for a task

Authorizations:
apiKeyAuth
path Parameters
taskId
required
string <uuid>

Responses

List participants of a task

Authorizations:
apiKeyAuth
path Parameters
taskId
required
string <uuid>

Responses

Add a participant to a task

Authorizations:
apiKeyAuth
path Parameters
taskId
required
string <uuid>
Request Body schema: application/json
required
member_id
required
string <uuid>
participation_type_id
string <uuid>

Responses

Request samples

Content type
application/json
{
  • "member_id": "435a4844-006a-4cfc-a644-e8eb2dd2ca43",
  • "participation_type_id": "126528fa-07da-43d8-8f06-0346eb2ecc74"
}

Remove a participant from a task

Authorizations:
apiKeyAuth
path Parameters
taskId
required
string <uuid>
participantId
required
string <uuid>

Responses

List a task's links to other tasks

Returns links in both directions: rows where this task is the source (direction: outgoing, link_type as stored) and rows where it's the target (direction: incoming). The scheduling types (finish_to_start, start_to_start, start_to_finish, finish_to_finish) keep the same link_type in both directions — use direction to tell predecessor from successor. duplicates inverts to is_duplicated_by; relates_to stays relates_to.

Authorizations:
apiKeyAuth
path Parameters
taskId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Link this task to another task

Creates a directional link from this task to linked_task_id of type link_type. Both tasks must belong to the caller's account. Fails 400 if linked_task_id is the same task, 404 if it doesn't exist in this account, and 409 if this exact (task, linked task, type) link already exists.

Authorizations:
apiKeyAuth
path Parameters
taskId
required
string <uuid>
Request Body schema: application/json
required
linked_task_id
required
string <uuid>
link_type
required
string (TaskLinkType)
Enum: "finish_to_start" "start_to_start" "start_to_finish" "finish_to_finish" "duplicates" "relates_to"

Responses

Request samples

Content type
application/json
{
  • "linked_task_id": "f058b6f0-fc6a-463d-9ff4-7b21347211ea",
  • "link_type": "finish_to_start"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Remove a task link

Removes the link regardless of whether taskId is the source or target side of it.

Authorizations:
apiKeyAuth
path Parameters
taskId
required
string <uuid>
linkId
required
string <uuid>

Responses

Tasklets

List tasklets

Authorizations:
apiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Create a tasklet

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
title
required
string
body
string
task_id
string <uuid>
assigned_to_member_id
string <uuid>
priority
string (TaskletPriority)
Enum: "low" "medium" "high" "critical"
due_at
string <date-time>

Responses

Request samples

Content type
application/json
{
  • "title": "string",
  • "body": "string",
  • "task_id": "736fde4d-9029-4915-8189-01353d6982cb",
  • "assigned_to_member_id": "f762546b-4e22-4cbc-845d-0a241ae61391",
  • "priority": "low",
  • "due_at": "2019-08-24T14:15:22Z"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get the last updated time for tasklets

Authorizations:
apiKeyAuth

Responses

Update a tasklet

Authorizations:
apiKeyAuth
path Parameters
id
required
string <uuid>
Request Body schema: application/json
title
string
body
string
status
string (TaskletStatus)
Enum: "open" "done" "snoozed" "cancelled"
priority
string (TaskletPriority)
Enum: "low" "medium" "high" "critical"
assigned_to_member_id
string <uuid>
due_at
string <date-time>
snooze_until
string <date-time>

Responses

Request samples

Content type
application/json
{
  • "title": "string",
  • "body": "string",
  • "status": "open",
  • "priority": "low",
  • "assigned_to_member_id": "f762546b-4e22-4cbc-845d-0a241ae61391",
  • "due_at": "2019-08-24T14:15:22Z",
  • "snooze_until": "2019-08-24T14:15:22Z"
}

List comments on a tasklet

Authorizations:
apiKeyAuth
path Parameters
id
required
string <uuid>

Responses

Add a comment to a tasklet

Authorizations:
apiKeyAuth
path Parameters
id
required
string <uuid>
Request Body schema: application/json
required
content
required
string

Responses

Request samples

Content type
application/json
{
  • "content": "string"
}

Labels

List all labels

Authorizations:
apiKeyAuth

Responses

Ideas

List ideas

Authorizations:
apiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Create an idea

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
title
required
string
description
string
product_id
required
string <uuid>

Responses

Request samples

Content type
application/json
{
  • "title": "string",
  • "description": "string",
  • "product_id": "0d012afa-f885-4e65-aeca-37e27701e2d1"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update an idea

Authorizations:
apiKeyAuth
path Parameters
ideaId
required
string <uuid>
Request Body schema: application/json
title
string
description
string

Responses

Request samples

Content type
application/json
{
  • "title": "string",
  • "description": "string"
}

Vote on an idea

Authorizations:
apiKeyAuth
path Parameters
ideaId
required
string <uuid>
Request Body schema: application/json
required
vote_type
required
string
Enum: "up" "down"

Responses

Request samples

Content type
application/json
{
  • "vote_type": "up"
}

Remove vote from an idea

Authorizations:
apiKeyAuth
path Parameters
ideaId
required
string <uuid>

Responses

Add a comment to an idea

Authorizations:
apiKeyAuth
path Parameters
ideaId
required
string <uuid>
Request Body schema: application/json
required
content
required
string

Responses

Request samples

Content type
application/json
{
  • "content": "string"
}

Initiatives

List initiatives

Authorizations:
apiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Create an initiative

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
name
required
string
product_id
required
string <uuid>
start_date
string <date-time>
end_date
string <date-time>

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "product_id": "0d012afa-f885-4e65-aeca-37e27701e2d1",
  • "start_date": "2019-08-24T14:15:22Z",
  • "end_date": "2019-08-24T14:15:22Z"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update an initiative

Authorizations:
apiKeyAuth
path Parameters
initiativeId
required
string <uuid>
Request Body schema: application/json
name
string
start_date
string <date-time>
end_date
string <date-time>

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "start_date": "2019-08-24T14:15:22Z",
  • "end_date": "2019-08-24T14:15:22Z"
}

Delete an initiative

Authorizations:
apiKeyAuth
path Parameters
initiativeId
required
string <uuid>

Responses

Objectives

List objectives

Authorizations:
apiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Create an objective

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
title
required
string
description
string
product_id
required
string <uuid>
objective_cycle_id
required
string <uuid>

Responses

Request samples

Content type
application/json
{
  • "title": "string",
  • "description": "string",
  • "product_id": "0d012afa-f885-4e65-aeca-37e27701e2d1",
  • "objective_cycle_id": "cfbba3a3-49ce-46d7-91a7-216179217e20"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update an objective

Authorizations:
apiKeyAuth
path Parameters
objectiveId
required
string <uuid>
Request Body schema: application/json
title
string
description
string

Responses

Request samples

Content type
application/json
{
  • "title": "string",
  • "description": "string"
}

Delete an objective

Authorizations:
apiKeyAuth
path Parameters
objectiveId
required
string <uuid>

Responses

Add a key result to an objective

Authorizations:
apiKeyAuth
path Parameters
objectiveId
required
string <uuid>
Request Body schema: application/json
required
title
required
string
description
string
metric_type
required
string (KeyResultMetricType)
Enum: "number" "percentage" "currency"
target_value
required
number
current_value
number
baseline_value
number

Responses

Request samples

Content type
application/json
{
  • "title": "string",
  • "description": "string",
  • "metric_type": "number",
  • "target_value": 0,
  • "current_value": 0,
  • "baseline_value": 0
}

Update a key result

Authorizations:
apiKeyAuth
path Parameters
objectiveId
required
string <uuid>
keyResultId
required
string <uuid>
Request Body schema: application/json
title
required
string
description
string
metric_type
required
string (KeyResultMetricType)
Enum: "number" "percentage" "currency"
target_value
required
number
current_value
number
baseline_value
number

Responses

Request samples

Content type
application/json
{
  • "title": "string",
  • "description": "string",
  • "metric_type": "number",
  • "target_value": 0,
  • "current_value": 0,
  • "baseline_value": 0
}

Delete a key result

Authorizations:
apiKeyAuth
path Parameters
objectiveId
required
string <uuid>
keyResultId
required
string <uuid>

Responses

ObjectiveCycles

List objective cycles

Authorizations:
apiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Create an objective cycle

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
name
required
string
product_id
required
string <uuid>
start_date
string <date-time>
end_date
string <date-time>

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "product_id": "0d012afa-f885-4e65-aeca-37e27701e2d1",
  • "start_date": "2019-08-24T14:15:22Z",
  • "end_date": "2019-08-24T14:15:22Z"
}

Update an objective cycle

Authorizations:
apiKeyAuth
path Parameters
objectiveCycleId
required
string <uuid>
Request Body schema: application/json
name
string
start_date
string <date-time>
end_date
string <date-time>

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "start_date": "2019-08-24T14:15:22Z",
  • "end_date": "2019-08-24T14:15:22Z"
}

Delete an objective cycle

Authorizations:
apiKeyAuth
path Parameters
objectiveCycleId
required
string <uuid>

Responses

Products

List products

Authorizations:
apiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Create a product

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
name
required
string
description
string
logo_url
string
visibility
string
Enum: "account" "members"
owner_member_id
string <uuid>
Array of objects (ProductLink)
object (ProductContext)

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "description": "string",
  • "logo_url": "string",
  • "visibility": "account",
  • "owner_member_id": "b0a041db-c5b2-49a1-b3f7-48acec826805",
  • "links": [
    ],
  • "context": {
    }
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get a product

Authorizations:
apiKeyAuth
path Parameters
productId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update a product

Authorizations:
apiKeyAuth
path Parameters
productId
required
string <uuid>
Request Body schema: application/json
name
string
description
string
logo_url
string
visibility
string
Enum: "account" "members"
owner_member_id
string <uuid>
Array of objects (ProductLink)
object (ProductContext)

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "description": "string",
  • "logo_url": "string",
  • "visibility": "account",
  • "owner_member_id": "b0a041db-c5b2-49a1-b3f7-48acec826805",
  • "links": [
    ],
  • "context": {
    }
}

Delete a product

Authorizations:
apiKeyAuth
path Parameters
productId
required
string <uuid>

Responses

Features

List features for a product

Authorizations:
apiKeyAuth
path Parameters
productId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Create a feature

Authorizations:
apiKeyAuth
path Parameters
productId
required
string <uuid>
Request Body schema: application/json
required
title
required
string
description
string

Responses

Request samples

Content type
application/json
{
  • "title": "string",
  • "description": "string"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Bulk create features

Authorizations:
apiKeyAuth
path Parameters
productId
required
string <uuid>
Request Body schema: application/json
required
Array of objects

Responses

Request samples

Content type
application/json
{
  • "features": [
    ]
}

Update a feature

Authorizations:
apiKeyAuth
path Parameters
productId
required
string <uuid>
featureId
required
string <uuid>
Request Body schema: application/json
title
string
description
string

Responses

Request samples

Content type
application/json
{
  • "title": "string",
  • "description": "string"
}

Delete a feature

Authorizations:
apiKeyAuth
path Parameters
productId
required
string <uuid>
featureId
required
string <uuid>

Responses

RoadmapItems

List roadmap items for a product

Authorizations:
apiKeyAuth
path Parameters
productId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Create a roadmap item

Authorizations:
apiKeyAuth
path Parameters
productId
required
string <uuid>
Request Body schema: application/json
required
title
required
string
description
string
feature_id
string <uuid>
initiative_id
string <uuid>
roadmap_planned_start_date
string <date-time>
roadmap_planned_end_date
string <date-time>
audience
Array of strings
confidence
integer
effort
integer

Responses

Request samples

Content type
application/json
{
  • "title": "string",
  • "description": "string",
  • "feature_id": "ba6c7b2c-38fc-4a78-a187-51c7bbbd5c50",
  • "initiative_id": "0a7d3437-c543-4aeb-80b3-0a1ef16d2ec1",
  • "roadmap_planned_start_date": "2019-08-24T14:15:22Z",
  • "roadmap_planned_end_date": "2019-08-24T14:15:22Z",
  • "audience": [
    ],
  • "confidence": 0,
  • "effort": 0
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update a roadmap item

Authorizations:
apiKeyAuth
path Parameters
productId
required
string <uuid>
roadmapItemId
required
string <uuid>
Request Body schema: application/json
title
string
description
string
feature_id
string or null <uuid>
initiative_id
string or null <uuid>
roadmap_planned_start_date
string <date-time>
roadmap_planned_end_date
string <date-time>
roadmap_actual_start_date
string <date-time>
roadmap_actual_end_date
string <date-time>
confidence
integer
effort
integer

Responses

Request samples

Content type
application/json
{
  • "title": "string",
  • "description": "string",
  • "feature_id": "ba6c7b2c-38fc-4a78-a187-51c7bbbd5c50",
  • "initiative_id": "0a7d3437-c543-4aeb-80b3-0a1ef16d2ec1",
  • "roadmap_planned_start_date": "2019-08-24T14:15:22Z",
  • "roadmap_planned_end_date": "2019-08-24T14:15:22Z",
  • "roadmap_actual_start_date": "2019-08-24T14:15:22Z",
  • "roadmap_actual_end_date": "2019-08-24T14:15:22Z",
  • "confidence": 0,
  • "effort": 0
}

Delete a roadmap item

Authorizations:
apiKeyAuth
path Parameters
productId
required
string <uuid>
roadmapItemId
required
string <uuid>

Responses

ProjectCycles

List project cycles (Phase / Release / Sprint)

Authorizations:
apiKeyAuth
query Parameters
filter
string

"key" operator "value" filter convention (see GET /customers for the general syntax). project_id (eq) is required. Supported keys: project_id (uuid), category (one of phase, release, sprint). Example: filter="project_id" eq "<uuid>";"category" eq "sprint".

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Create a project cycle

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
project_id
required
string <uuid>
category
required
string
Enum: "phase" "release" "sprint"
label
required
string
color
string or null
description
string or null
start_date
required
string <date-time>
end_date
required
string <date-time>
parent_project_cycle_id
string or null <uuid>

Responses

Request samples

Content type
application/json
{
  • "project_id": "405d8375-3514-403b-8c43-83ae74cfe0e9",
  • "category": "phase",
  • "label": "string",
  • "color": "string",
  • "description": "string",
  • "start_date": "2019-08-24T14:15:22Z",
  • "end_date": "2019-08-24T14:15:22Z",
  • "parent_project_cycle_id": "004a3774-9f56-4dc7-9d8e-a0fb64154480"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get a project cycle

Authorizations:
apiKeyAuth
path Parameters
projectCycleId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update a project cycle

Authorizations:
apiKeyAuth
path Parameters
projectCycleId
required
string <uuid>
Request Body schema: application/json
label
string
color
string or null
description
string or null
start_date
string <date-time>
end_date
string <date-time>
parent_project_cycle_id
string or null <uuid>

Responses

Request samples

Content type
application/json
{
  • "label": "string",
  • "color": "string",
  • "description": "string",
  • "start_date": "2019-08-24T14:15:22Z",
  • "end_date": "2019-08-24T14:15:22Z",
  • "parent_project_cycle_id": "004a3774-9f56-4dc7-9d8e-a0fb64154480"
}

Delete a project cycle

Authorizations:
apiKeyAuth
path Parameters
projectCycleId
required
string <uuid>

Responses

Milestones

List milestones

Authorizations:
apiKeyAuth
query Parameters
filter
string

"key" operator "value" filter convention (see GET /customers for the general syntax). project_id (eq) is required. Supported keys: project_id (uuid). Example: filter="project_id" eq "<uuid>".

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Create a milestone

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
project_id
required
string <uuid>
title
required
string
target_date
required
string <date-time>
description
string or null

Responses

Request samples

Content type
application/json
{
  • "project_id": "405d8375-3514-403b-8c43-83ae74cfe0e9",
  • "title": "string",
  • "target_date": "2019-08-24T14:15:22Z",
  • "description": "string"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get a milestone

Authorizations:
apiKeyAuth
path Parameters
milestoneId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update a milestone

Authorizations:
apiKeyAuth
path Parameters
milestoneId
required
string <uuid>
Request Body schema: application/json
title
string
target_date
string <date-time>
description
string or null

Responses

Request samples

Content type
application/json
{
  • "title": "string",
  • "target_date": "2019-08-24T14:15:22Z",
  • "description": "string"
}

Delete a milestone

Authorizations:
apiKeyAuth
path Parameters
milestoneId
required
string <uuid>

Responses

Documents

List documents

Each document's title/content/context/type/status/version reflect its current published version.

Authorizations:
apiKeyAuth
query Parameters
project_id
string <uuid>
product_id
string <uuid>
type
string (DocumentType)
Enum: "general" "feedback" "requirement"

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Create a document

Creates the document with version 1, published immediately.

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
title
required
string
content
string or null
type
string (DocumentType)
Enum: "general" "feedback" "requirement"
project_id
string or null <uuid>
product_id
string or null <uuid>
context
object

Responses

Request samples

Content type
application/json
{
  • "title": "string",
  • "content": "string",
  • "type": "general",
  • "project_id": "405d8375-3514-403b-8c43-83ae74cfe0e9",
  • "product_id": "0d012afa-f885-4e65-aeca-37e27701e2d1",
  • "context": { }
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get a document

Returns the document's current published version.

Authorizations:
apiKeyAuth
path Parameters
documentId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update a document

Edits the current published version's fields in place. This does not create a new version or change the version number — for that, use POST /documents/{documentId}/versions. project_id/product_id are container fields on the document itself and update the same way either way.

Authorizations:
apiKeyAuth
path Parameters
documentId
required
string <uuid>
Request Body schema: application/json
title
string
content
string
type
string (DocumentType)
Enum: "general" "feedback" "requirement"
project_id
string or null <uuid>
product_id
string or null <uuid>
context
object

Responses

Request samples

Content type
application/json
{
  • "title": "string",
  • "content": "string",
  • "type": "general",
  • "project_id": "405d8375-3514-403b-8c43-83ae74cfe0e9",
  • "product_id": "0d012afa-f885-4e65-aeca-37e27701e2d1",
  • "context": { }
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Delete a document

Cascades to delete all of the document's versions (current and archived).

Authorizations:
apiKeyAuth
path Parameters
documentId
required
string <uuid>

Responses

List a document's versions

Includes the current published version plus all archived (superseded) versions, newest version number first.

Authorizations:
apiKeyAuth
path Parameters
documentId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Create a new version

Archives the current published version and creates the next one (version + 1), published immediately. All fields are optional and default to the current version's values if omitted, so calling this with an empty body is a pure snapshot/clone; passing any of them sets the new version's content in the same call instead of requiring a follow-up PATCH.

Authorizations:
apiKeyAuth
path Parameters
documentId
required
string <uuid>
Request Body schema: application/json
title
string
content
string
type
string (DocumentType)
Enum: "general" "feedback" "requirement"
context
object

Responses

Request samples

Content type
application/json
{
  • "title": "string",
  • "content": "string",
  • "type": "general",
  • "context": { }
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get a single document version

Authorizations:
apiKeyAuth
path Parameters
documentId
required
string <uuid>
versionId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Acknowledgements

List acknowledgements

Authorizations:
apiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Create an acknowledgement

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
subject_type
required
string
subject_id
required
string <uuid>
subject_version
required
string
scope_type
string or null
scope_id
string or null <uuid>

Responses

Request samples

Content type
application/json
{
  • "subject_type": "string",
  • "subject_id": "80e197be-61ad-4068-b4ff-a483fb5c18f9",
  • "subject_version": "string",
  • "scope_type": "string",
  • "scope_id": "5d3fe357-12dd-4f62-b004-6d1fb3b8454f"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Forms

List forms

Authorizations:
apiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Create a form

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
title
required
string
description
string
project_id
string or null <uuid>
product_id
string or null <uuid>
status
string
Enum: "draft" "published" "closed"
success_message
string
Array of objects (FormField)

Responses

Request samples

Content type
application/json
{
  • "title": "string",
  • "description": "string",
  • "project_id": "405d8375-3514-403b-8c43-83ae74cfe0e9",
  • "product_id": "0d012afa-f885-4e65-aeca-37e27701e2d1",
  • "status": "draft",
  • "success_message": "string",
  • "fields": [
    ]
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get a form

Authorizations:
apiKeyAuth
path Parameters
form_id
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update a form

Authorizations:
apiKeyAuth
path Parameters
form_id
required
string <uuid>
Request Body schema: application/json
title
string
description
string
status
string
Enum: "draft" "published" "closed"
success_message
string
Array of objects (FormField)

Responses

Request samples

Content type
application/json
{
  • "title": "string",
  • "description": "string",
  • "status": "draft",
  • "success_message": "string",
  • "fields": [
    ]
}

List responses for a form

Authorizations:
apiKeyAuth
path Parameters
form_id
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": [
    ]
}

Submit a response against an internal resource

Authenticated counterpart to POST /public/forms/{form_id}/responses. That endpoint is for anonymous external submissions (e.g. a customer feedback form) and never links to a resource. This one is for a logged-in member executing a form against a resource they're looking at -- e.g. an SOP checklist (see SopTemplate) executed against a maintenance request or housekeeping task -- so it records who submitted it and what it's attached to, and can fire the form_response_submitted Automation trigger.

response is validated against the form's fields (required fields enforced, respecting conditional visibility) the same way the public endpoint validates it.

Authorizations:
apiKeyAuth
path Parameters
form_id
required
string <uuid>
Request Body schema: application/json
required
response
required
object

field id -> submitted value, keyed by the form's FormField.id.

resource_type
string or null
Value: "task"

When set (with resource_id), also dispatches the form_response_submitted Automation trigger for that task's entity_type.

resource_id
string or null <uuid>

Responses

Request samples

Content type
application/json
{
  • "response": { },
  • "resource_type": "task",
  • "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

CustomFields

List custom fields

Authorizations:
apiKeyAuth
query Parameters
resource_type
string

When set, excludes fields whose resource_types is non-empty and doesn't include this value.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Create a custom field

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
name
required
string
key
required
string
description
string
field_type
required
string (CustomFieldType)
Enum: "text" "number" "date" "boolean" "select" "multi_select" "url" "email" "phone" "money" "member" "form" "workstream" "project" "customer" "customer.person"
object (CustomFieldConfig)
resource_types
Array of strings or null
Enum: "task" "deal" "customer" "product" "invoice"

Restricts which resource types this field can attach to (e.g. ["deal"]). Omit/null to apply to all resource types.

is_required
boolean
show_on_pdf
boolean

When true, renders this field's value on generated PDFs for resources that support them (currently only Invoice). Defaults to false.

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "key": "string",
  • "description": "string",
  • "field_type": "text",
  • "config": {
    },
  • "resource_types": [
    ],
  • "is_required": true,
  • "show_on_pdf": true
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get a custom field

Authorizations:
apiKeyAuth
path Parameters
customFieldId
required
string <uuid>

Responses

Update a custom field

Authorizations:
apiKeyAuth
path Parameters
customFieldId
required
string <uuid>
Request Body schema: application/json
name
string
description
string
object (CustomFieldConfig)
resource_types
Array of strings or null
Enum: "task" "deal" "customer" "product" "invoice"
is_required
boolean
show_on_pdf
boolean

When true, renders this field's value on generated PDFs for resources that support them (currently only Invoice). Defaults to false.

is_active
boolean

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "description": "string",
  • "config": {
    },
  • "resource_types": [
    ],
  • "is_required": true,
  • "show_on_pdf": true,
  • "is_active": true
}

Delete a custom field

Authorizations:
apiKeyAuth
path Parameters
customFieldId
required
string <uuid>

Responses

Set values for a custom field

Authorizations:
apiKeyAuth
path Parameters
customFieldId
required
string <uuid>
Request Body schema: application/json
required
object

Responses

Request samples

Content type
application/json
{ }

Delete a custom field value

Authorizations:
apiKeyAuth
path Parameters
valueId
required
string <uuid>

Responses

Get custom field values for a specific resource

Authorizations:
apiKeyAuth
path Parameters
resourceType
required
string
resourceId
required
string <uuid>

Responses

EntityWorkflowTemplates

Reorder workflow template stages

Authorizations:
apiKeyAuth
path Parameters
workflowTemplateId
required
string <uuid>
Request Body schema: application/json
required
stage_ids
Array of strings <uuid> [ items <uuid > ]

Responses

Request samples

Content type
application/json
{
  • "stage_ids": [
    ]
}

Add a stage to a workflow template

start_event_key/end_event_key (and start_event_name/end_event_name) must each be unique across every stage's start/end event in this workflow template. is_system is never client-settable -- system events are seeded internally (e.g. the "Delivered" event on a delivery workflow's "done" stage).

Authorizations:
apiKeyAuth
path Parameters
workflowTemplateId
required
string <uuid>
Request Body schema: application/json
required
name
required
string
description
string
color
string
start_event_name
string or null
start_event_key
string or null

Stable identifier for the stage's start event, unique across the workflow template.

end_event_name
string or null
end_event_key
string or null

Stable identifier for the stage's end event, unique across the workflow template.

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "description": "string",
  • "color": "string",
  • "start_event_name": "string",
  • "start_event_key": "string",
  • "end_event_name": "string",
  • "end_event_key": "string"
}

Update a workflow template stage

Authorizations:
apiKeyAuth
path Parameters
workflowTemplateId
required
string <uuid>
workflowTemplateStageId
required
string <uuid>
Request Body schema: application/json
name
string
description
string
color
string
start_event_name
string or null
start_event_key
string or null
end_event_name
string or null
end_event_key
string or null

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "description": "string",
  • "color": "string",
  • "start_event_name": "string",
  • "start_event_key": "string",
  • "end_event_name": "string",
  • "end_event_key": "string"
}

Delete a workflow template stage

Authorizations:
apiKeyAuth
path Parameters
workflowTemplateId
required
string <uuid>
workflowTemplateStageId
required
string <uuid>

Responses

List fields available for stage conditions

Returns the built-in task fields plus the account's active custom fields, each with its data type and the condition operators valid for that data type. Use this to build the condition-builder UI.

Authorizations:
apiKeyAuth
path Parameters
workflowTemplateId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

List entry conditions for a workflow template stage

Authorizations:
apiKeyAuth
path Parameters
workflowTemplateId
required
string <uuid>
workflowTemplateStageId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Add an entry condition to a workflow template stage

A task can only move into this stage once all of its conditions are satisfied (see POST /tasks/{taskId}/workflow_stages). The operator must be valid for the target field's data type — fetch valid fields/operators from GET .../condition-fields first.

Authorizations:
apiKeyAuth
path Parameters
workflowTemplateId
required
string <uuid>
workflowTemplateStageId
required
string <uuid>
Request Body schema: application/json
required
field_source
required
string (StageConditionFieldSource)
Enum: "custom_field" "task_field"
custom_field_id
string <uuid>

Required when field_source is custom_field.

task_field
string

Required when field_source is task_field. One of the fields returned by GET /entity-workflow-templates/{workflowTemplateId}/condition-fields.

operator
required
string (StageConditionOperator)
Enum: "equals" "not_equals" "contains" "not_contains" "is_empty" "is_not_empty" "gt" "gte" "lt" "lte" "in" "not_in"
value
any

Responses

Request samples

Content type
application/json
{
  • "field_source": "custom_field",
  • "custom_field_id": "a0fa4fc5-cabd-4219-9751-6d126c809065",
  • "task_field": "string",
  • "operator": "equals",
  • "value": null
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Remove an entry condition from a workflow template stage

Authorizations:
apiKeyAuth
path Parameters
workflowTemplateId
required
string <uuid>
workflowTemplateStageId
required
string <uuid>
conditionId
required
string <uuid>

Responses

List required approvers for a workflow template stage

Authorizations:
apiKeyAuth
path Parameters
workflowTemplateId
required
string <uuid>
workflowTemplateStageId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Require an approver participation type for a workflow template stage

Once one or more approvers are configured for a stage, a task cannot move into that stage until a member holding each required participation type on the task has approved via POST /tasks/{taskId}/workflow_stages/{stageId}/approvals (or the mover has the task.stage.bypass_approval permission).

Authorizations:
apiKeyAuth
path Parameters
workflowTemplateId
required
string <uuid>
workflowTemplateStageId
required
string <uuid>
Request Body schema: application/json
required
entity_user_participation_type_id
required
string <uuid>

Responses

Request samples

Content type
application/json
{
  • "entity_user_participation_type_id": "23f2e07a-d7b4-45d9-8d71-31226db54e3f"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Remove a required approver from a workflow template stage

Authorizations:
apiKeyAuth
path Parameters
workflowTemplateId
required
string <uuid>
workflowTemplateStageId
required
string <uuid>
approverId
required
string <uuid>

Responses

Entities

List entities

Returns every entity (workstream, bundle, and deal_pipeline) the account can create tasks against, each with its workflow_template and stages (including each stage's required approvers) nested.

Authorizations:
apiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

List participation types for an entity

Works for any entity type, including the singleton entities backing procurement/deal/facility task workflows (e.g. purchase_requisition, purchase_order, bill, deal_pipeline), not just workstreams. Each type is returned with its allowed_participants nested (empty array means unrestricted).

Authorizations:
apiKeyAuth
path Parameters
entityId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Add a participation type to an entity

Authorizations:
apiKeyAuth
path Parameters
entityId
required
string <uuid>
Request Body schema: application/json
required
name
required
string
description
string

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "description": "string"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update a participation type

Authorizations:
apiKeyAuth
path Parameters
entityId
required
string <uuid>
typeId
required
string <uuid>
Request Body schema: application/json
name
string
description
string

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "description": "string"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Delete a participation type

Authorizations:
apiKeyAuth
path Parameters
entityId
required
string <uuid>
typeId
required
string <uuid>

Responses

List allowed participants for a participation type

The configured allow-list of members eligible to be assigned this participation type on a task. An empty list means unrestricted (any account member may be assigned).

Authorizations:
apiKeyAuth
path Parameters
entityId
required
string <uuid>
typeId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Add a member to a participation type's allow-list

Once one or more allowed participants are configured for a participation type, only those members may be assigned that type via POST /tasks/{taskId}/participants; the API returns 403 for any other member. Adding the first entry switches the type from unrestricted to restricted.

Authorizations:
apiKeyAuth
path Parameters
entityId
required
string <uuid>
typeId
required
string <uuid>
Request Body schema: application/json
required
member_id
required
string <uuid>

Responses

Request samples

Content type
application/json
{
  • "member_id": "435a4844-006a-4cfc-a644-e8eb2dd2ca43"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Remove a member from a participation type's allow-list

Does not retroactively affect members already assigned that participation type on existing tasks.

Authorizations:
apiKeyAuth
path Parameters
entityId
required
string <uuid>
typeId
required
string <uuid>
allowedParticipantId
required
string <uuid>

Responses

Customers

List customers

Includes each customer's contacts.

Authorizations:
apiKeyAuth
query Parameters
filter
string

"key" operator "value" filter convention, e.g. filter="name" iLike "%acme%" (URL-encoded). Key and value must each be valid JSON, so strings need quotes and arrays/numbers are passed as-is (e.g. "in" expects a JSON array value). Chain multiple conditions with ;, e.g. filter="status" eq "active";"name" iLike "%acme%". Supported operators: eq, ne, in, iLike, gt, gte, lt, lte, is. Only a per-endpoint whitelist of keys is honored; unsupported keys are silently ignored. Supported keys here: name, status, type (one of business, individual, unknown), contact_value (matches a customer having a contact whose phone number or email equals, or with iLike, matches the given value, e.g. filter="contact_value" iLike "%@acme.com%").

sort_by
string
Enum: "name" "status" "created_at"
sort_order
string
Enum: "asc" "desc"

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Create a customer

Includes the customer's contacts in the response.

Optionally accepts a contacts array to create contacts in the same request. An individual customer can have at most one contact: the request is rejected with a 400 if type is (or defaults to) individual and more than one contact is supplied.

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
name
required
string
type
string
Default: "business"
Enum: "business" "individual"

An individual customer can have at most one contact. Defaults to business if omitted.

status
string

Defaults to the first entry in the account's customer_status_options if omitted.

preferences
object
object

Shallow-merged into preferences.billing_details; lets callers set billing fields without resending the whole preferences object.

customer_account_id
string <uuid>
Array of objects

Contacts to create alongside this customer.

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "type": "business",
  • "status": "string",
  • "preferences": { },
  • "billing_details": {
    },
  • "customer_account_id": "94d11de5-c19a-403b-bfd6-219437a0391d",
  • "contacts": [
    ]
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get the account's configured customer status options

Authorizations:
apiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Replace the account's configured customer status options

Purely a config write — does not alter the status field on already-created customers.

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
statuses
required
Array of strings non-empty

Responses

Request samples

Content type
application/json
{
  • "statuses": [
    ]
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get a customer

Includes the customer's contacts.

Authorizations:
apiKeyAuth
path Parameters
customerId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update a customer

Includes the customer's contacts in the response.

Optionally accepts a contacts array to create contacts in the same request — useful when changing type from individual to business and adding contacts at the same time. An individual customer can have at most one contact: the request is rejected with a 400 if applying type and contacts together (accounting for any contacts the customer already has) would leave an individual customer with more than one contact.

Authorizations:
apiKeyAuth
path Parameters
customerId
required
string <uuid>
Request Body schema: application/json
name
string
type
string
Enum: "business" "individual"
status
string or null
preferences
object
object

Shallow-merged into preferences.billing_details; lets callers set billing fields without resending the whole preferences object.

Array of objects

Contacts to create alongside this update.

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "type": "business",
  • "status": "string",
  • "preferences": { },
  • "billing_details": {
    },
  • "contacts": [
    ]
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Delete a customer

Authorizations:
apiKeyAuth
path Parameters
customerId
required
string <uuid>

Responses

Merge a customer with type "unknown" into an existing customer

Only customers with type "unknown" (auto-created from an unrecognized inbound WhatsApp sender) can be merged. If target_contact_id is given, the unknown customer's contact methods (e.g. its WhatsApp phone number) are folded into that existing contact and the unknown customer's own contact is removed; otherwise the unknown customer's contact is re-parented onto the target customer as a new contact (rejected with 400 if the target is an "individual" customer that would end up with more than one contact). All of the unknown customer's CustomerInteraction and WhatsappMessage history is re-pointed to the target customer so nothing is lost, then the unknown customer record is deleted. Returns the updated target customer with its contacts.

Authorizations:
apiKeyAuth
path Parameters
customerId
required
string <uuid>
Request Body schema: application/json
required
target_customer_id
required
string <uuid>

The existing customer to merge this "unknown" customer into.

target_contact_id
string <uuid>

An existing contact on the target customer to fold this customer's contact methods into. Omit to add this customer's contact as a new contact on the target customer instead.

Responses

Request samples

Content type
application/json
{
  • "target_customer_id": "9a7db571-de2c-4560-a242-b038e423cb7f",
  • "target_contact_id": "d21b38de-63b2-4b14-8b04-5c0d17bd89a0"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

List contacts for a customer

Authorizations:
apiKeyAuth
path Parameters
customerId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Add a contact to a customer

An individual customer can have at most one contact.

Authorizations:
apiKeyAuth
path Parameters
customerId
required
string <uuid>
Request Body schema: application/json
required
first_name
required
string
last_name
required
string
role
string or null
Array of objects (ContactMethod)
is_primary
boolean

Responses

Request samples

Content type
application/json
{
  • "first_name": "string",
  • "last_name": "string",
  • "role": "string",
  • "contact_methods": [
    ],
  • "is_primary": true
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update a contact

Authorizations:
apiKeyAuth
path Parameters
customerId
required
string <uuid>
contactId
required
string <uuid>
Request Body schema: application/json
first_name
string
last_name
string
role
string or null
Array of objects (ContactMethod)
is_primary
boolean

Responses

Request samples

Content type
application/json
{
  • "first_name": "string",
  • "last_name": "string",
  • "role": "string",
  • "contact_methods": [
    ],
  • "is_primary": true
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Remove a contact

Authorizations:
apiKeyAuth
path Parameters
customerId
required
string <uuid>
contactId
required
string <uuid>

Responses

List interactions (calls, emails, meetings, notes) logged against a customer

Authorizations:
apiKeyAuth
path Parameters
customerId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Log an interaction against a customer

Authorizations:
apiKeyAuth
path Parameters
customerId
required
string <uuid>
Request Body schema: application/json
required
contact_id
string <uuid>
type
required
string (CustomerInteractionType)
Enum: "call" "email" "meeting" "note" "whatsapp" "instagram"
subject
string or null
content
string or null
occurred_at
string <date-time>

Responses

Request samples

Content type
application/json
{
  • "contact_id": "f245e2a3-e141-4d41-912c-b1c1f5bd5598",
  • "type": "call",
  • "subject": "string",
  • "content": "string",
  • "occurred_at": "2019-08-24T14:15:22Z"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update a logged interaction

Authorizations:
apiKeyAuth
path Parameters
customerId
required
string <uuid>
interactionId
required
string <uuid>
Request Body schema: application/json
type
string (CustomerInteractionType)
Enum: "call" "email" "meeting" "note" "whatsapp" "instagram"
subject
string or null
content
string or null
occurred_at
string <date-time>

Responses

Request samples

Content type
application/json
{
  • "type": "call",
  • "subject": "string",
  • "content": "string",
  • "occurred_at": "2019-08-24T14:15:22Z"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Delete a logged interaction

Authorizations:
apiKeyAuth
path Parameters
customerId
required
string <uuid>
interactionId
required
string <uuid>

Responses

Vendors

List vendors

Authorizations:
apiKeyAuth
query Parameters
filter
string

"key" operator "value" filter convention, e.g. filter="name" iLike "%acme%" (URL-encoded). Key and value must each be valid JSON, so strings need quotes and arrays/numbers are passed as-is (e.g. "in" expects a JSON array value). Chain multiple conditions with ;, e.g. filter="type" eq "business";"name" iLike "%acme%". Supported operators: eq, ne, in, iLike, gt, gte, lt, lte, is. Only a per-endpoint whitelist of keys is honored; unsupported keys are silently ignored. Supported keys here: name, type, category.

sort_by
string
Enum: "name" "created_at"
sort_order
string
Enum: "asc" "desc"
limit
integer <= 100
Default: 20
offset
integer
Default: 0

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Create a vendor

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
name
required
string
type
string
Default: "business"
Enum: "business" "individual"
category
string or null

Free-text service/supply category (e.g. "hvac_maintenance", "electrician"). No fixed enum.

tax_type
string or null
tax_id
string or null
billing_address
object
notes
string or null
preferences
object
Array of objects

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "type": "business",
  • "category": "string",
  • "tax_type": "string",
  • "tax_id": "string",
  • "billing_address": { },
  • "notes": "string",
  • "preferences": { },
  • "contacts": [
    ]
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get a vendor

Authorizations:
apiKeyAuth
path Parameters
vendorId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update a vendor

Contacts are managed via the dedicated /vendors/{vendorId}/contacts endpoints, not through this endpoint.

Authorizations:
apiKeyAuth
path Parameters
vendorId
required
string <uuid>
Request Body schema: application/json
name
string
type
string
Enum: "business" "individual"
category
string or null

Free-text service/supply category (e.g. "hvac_maintenance", "electrician"). No fixed enum.

tax_type
string or null
tax_id
string or null
billing_address
object
notes
string or null
preferences
object

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "type": "business",
  • "category": "string",
  • "tax_type": "string",
  • "tax_id": "string",
  • "billing_address": { },
  • "notes": "string",
  • "preferences": { }
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Delete a vendor

Authorizations:
apiKeyAuth
path Parameters
vendorId
required
string <uuid>

Responses

List contacts for a vendor

Authorizations:
apiKeyAuth
path Parameters
vendorId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Add a contact to a vendor

Authorizations:
apiKeyAuth
path Parameters
vendorId
required
string <uuid>
Request Body schema: application/json
required
first_name
required
string
last_name
required
string
role
string or null
Array of objects (ContactMethod)
is_primary
boolean

Responses

Request samples

Content type
application/json
{
  • "first_name": "string",
  • "last_name": "string",
  • "role": "string",
  • "contact_methods": [
    ],
  • "is_primary": true
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update a vendor contact

Authorizations:
apiKeyAuth
path Parameters
vendorId
required
string <uuid>
vendorContactId
required
string <uuid>
Request Body schema: application/json
first_name
string
last_name
string
role
string or null
Array of objects (ContactMethod)
is_primary
boolean

Responses

Request samples

Content type
application/json
{
  • "first_name": "string",
  • "last_name": "string",
  • "role": "string",
  • "contact_methods": [
    ],
  • "is_primary": true
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Remove a vendor contact

Authorizations:
apiKeyAuth
path Parameters
vendorId
required
string <uuid>
vendorContactId
required
string <uuid>

Responses

List materials purchased from a vendor

Historical purchase records for materials bought from this vendor, as a union across purchase order line items (line_items JSONB on purchase_order_detail), delivery_line_item, and bill_line_item -- one row per line item, not deduplicated by material. Includes the price paid at the time of purchase (unit_price, normalized to a decimal amount; bill line items store unit_amount_cents which is divided by 100). Purchase orders/deliveries/bills carry their own vendor_id independent of each other (a delivery or bill need not originate from a PO), so all three sources are queried regardless of whether they're linked.

Authorizations:
apiKeyAuth
path Parameters
vendorId
required
string <uuid>
query Parameters
filter
string

"key" operator "value" filter convention (see GET /vendors for the general syntax). Supported operators here: eq, ne, in for material_id and source_type (purchase_order, delivery, or bill); gte/lte for purchased_at. e.g. filter="source_type" eq "bill";"purchased_at" gte "2026-01-01".

limit
integer <= 100
Default: 20
offset
integer
Default: 0

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Bills

List bills

Lists tasks joined with their bill_detail and vendor. Bills all live in the account's single, lazily provisioned "Bills" entity (workflow stages Pending Approval -> Approved -> Cleared).

Authorizations:
apiKeyAuth
query Parameters
filter
string

key operator value filter convention (see GET /customers for the general syntax). Supported keys: title, priority, due_at, assigned_to_member_id, participant_member_id, created_at, id (Task fields), material_id (matches bills with at least one line item for the given material_id -- eq/in/ne only), current_stage_id (matches the workflow_template_stage_id of the bill's current (latest) workflow stage -- eq/in/ne only), and vendor_id, location_id, is_flagged, bill_date, bill_number, vendor_bill_number, created_by_member_id (bill_detail fields). Or use GET /bills/dashboard-data for stage-level aggregates.

limit
integer <= 100
Default: 20
offset
integer
Default: 0

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Create a bill

Creates a Task in the account's Bills entity (plus its bill_detail row), lazily provisioning the entity and its Pending Approval / Approved / Cleared workflow on first use. vendor_id must refer to a vendor owned by this account. bill_number (our internal number, distinct from vendor_bill_number) is auto-generated from the account's current bill numbering settings (see /bills/settings/numbering) if omitted, snapshotted at creation time.

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
title
required
string
description
string
vendor_id
required
string <uuid>
location_id
string or null <uuid>

Must refer to a location owned by this account.

required
object (Money)
Array of objects (BillLineItem)
purchase_order_task_id
string or null <uuid>
vendor_bill_number
string or null

The vendor's own invoice/bill reference number, entered manually.

bill_number
string or null

Our internal bill number. Auto-generated from account settings if omitted; pass a value to override.

bill_date
string or null <date>
notes
string or null
priority
string (TaskPriority)
Enum: "high" "medium" "low"
due_at
string <date-time>
assigned_to_member_id
string <uuid>

Responses

Request samples

Content type
application/json
{
  • "title": "string",
  • "description": "string",
  • "vendor_id": "98232994-9d54-43ee-a280-d7c895362d0c",
  • "location_id": "46910cc3-ab41-4b80-b4a7-94dab9f1b795",
  • "amount": {
    },
  • "line_items": [
    ],
  • "purchase_order_task_id": "7c776152-0a17-416d-a60e-8bb19184c771",
  • "vendor_bill_number": "string",
  • "bill_number": "string",
  • "bill_date": "2019-08-24",
  • "notes": "string",
  • "priority": "high",
  • "due_at": "2019-08-24T14:15:22Z",
  • "assigned_to_member_id": "f762546b-4e22-4cbc-845d-0a241ae61391"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get the account's bill numbering settings

Authorizations:
apiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update the account's bill numbering prefix and/or reset the counter

A manual settings action -- purely a config write, never alters bill_number on already-created bills. Only affects the internally generated bill_number, not vendor_bill_number.

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
prefix
string non-empty
reset_counter_to
integer >= 0

Responses

Request samples

Content type
application/json
{
  • "prefix": "string",
  • "reset_counter_to": 0
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get aggregate dashboard data for the bills workflow

Returns account-wide stats for the bills overview dashboard: counts and value totals by status (grouped by currency, never summed across currencies), count and value of flagged bills, average clearance time, a breakdown by workflow stage (ordered by stage_order), bills due in the next 14 days that are not yet cleared, and the top 10 highest-value bills that are not yet cleared. Returns zeroed/empty fields if the account has no bill yet (the Bills entity is provisioned lazily on first bill creation).

Authorizations:
apiKeyAuth
query Parameters
filter
string

Same key operator value filter convention as GET /bills, but with its own narrower key whitelist. Supported keys: assigned_to_member_id, participant_member_id, created_at (Task fields), and vendor_id, location_id, bill_date (bill_detail fields).

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get bills summary grouped by category and vendor

Returns total bill amount for the time range, plus the same total broken down by status (total_value, pending_approval_value, cleared_value, flagged_value) and grouped two ways: by_category (stock vs. other_charges, derived from whether each line item carries a material_id) and by_vendor. Values are grouped by currency, never summed across currencies. Each by_category / by_vendor group also carries status: the current workflow stage name of the least-progressed bill in that group (e.g. if any bill in the group is still "Pending Approval", the group's status is "Pending Approval"), ignoring cancelled bills. Each by_category group also carries distinct_count (distinct materials for "stock", line item count for "other_charges"), and each by_vendor group carries material_count (distinct materials across that vendor's bills). Currently only supported for client_type site_management, plantops, and venueops -- the requesting account's client_type must match the path parameter, and the path parameter must currently be site_management, plantops, or venueops (other client types don't have a defined category grouping yet). Returns zeroed/empty fields if the account has no bill yet.

Authorizations:
apiKeyAuth
path Parameters
clientType
required
string (AccountClientType)
Enum: "app" "restora" "site_management" "plantops" "venueops"

Must match the requesting account's client_type. Only site_management, plantops, and venueops are currently supported.

query Parameters
filter
string

Same key operator value filter convention as GET /bills. Supported keys: created_at (Task field), and bill_date, vendor_id, location_id (bill_detail fields). Use bill_date with gte/lte operators for the time range filter.

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get bills summary for a single vendor, grouped by resource

Same shape as GET /bills/summary/{clientType}, but scoped to one vendor: total_value, pending_approval_value, cleared_value, flagged_value (all for this vendor's bills only), plus by_resource -- grouped by material_id instead of the stock/other_charges split (each distinct material gets its own row, and all line items with no material_id collapse into a single "other_charges" row). Values are grouped by currency, never summed across currencies. Each by_resource group also carries status: the current workflow stage name of the least-progressed bill in that group, ignoring cancelled bills, and item_count: the number of line items in the group. Currently only supported for client_type site_management, plantops, and venueops -- the requesting account's client_type must match the path parameter. Returns zeroed/empty fields if the vendor has no bill yet.

Authorizations:
apiKeyAuth
path Parameters
clientType
required
string (AccountClientType)
Enum: "app" "restora" "site_management" "plantops" "venueops"

Must match the requesting account's client_type. Only site_management, plantops, and venueops are currently supported.

vendorId
required
string <uuid>
query Parameters
filter
string

Same key operator value filter convention as GET /bills. Supported keys: created_at (Task field), and bill_date, location_id (bill_detail fields). Use bill_date with gte/lte operators for the time range filter. vendor_id cannot be filtered here -- it's fixed by the vendorId path parameter.

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get bills summary grouped by material

Same shape as GET /bills/summary/{clientType}/vendor/{vendorId}, but account-wide instead of scoped to one vendor, and restricted to stock line items: total_value, pending_approval_value, cleared_value, flagged_value (across all bills matching the filter), plus by_material -- one row per distinct material_id. Unlike by_resource on the vendor-scoped endpoint, line items with no material_id ("other_charges") are excluded entirely rather than collapsed into a group. Values are grouped by currency, never summed across currencies. Each by_material group also carries status: the current workflow stage name of the least-progressed bill in that group, ignoring cancelled bills, and item_count: the number of line items tagged with that material_id. Currently only supported for client_type site_management, plantops, and venueops -- the requesting account's client_type must match the path parameter. Returns zeroed/empty fields if the account has no bill yet.

Authorizations:
apiKeyAuth
path Parameters
clientType
required
string (AccountClientType)
Enum: "app" "restora" "site_management" "plantops" "venueops"

Must match the requesting account's client_type. Only site_management, plantops, and venueops are currently supported.

query Parameters
filter
string

Same key operator value filter convention as GET /bills. Supported keys: created_at (Task field), and bill_date, vendor_id, location_id (bill_detail fields). Use bill_date with gte/lte operators for the time range filter.

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get a bill

Authorizations:
apiKeyAuth
path Parameters
billId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update a bill

Authorizations:
apiKeyAuth
path Parameters
billId
required
string <uuid>
Request Body schema: application/json
title
string
description
string
vendor_id
string <uuid>
location_id
string or null <uuid>

Must refer to a location owned by this account. Pass null to unlink.

object (Money)
Array of objects (BillLineItem)
purchase_order_task_id
string or null <uuid>
vendor_bill_number
string or null
bill_number
string or null
bill_date
string or null <date>
notes
string or null
priority
string (TaskPriority)
Enum: "high" "medium" "low"
due_at
string <date-time>
assigned_to_member_id
string <uuid>

Responses

Request samples

Content type
application/json
{
  • "title": "string",
  • "description": "string",
  • "vendor_id": "98232994-9d54-43ee-a280-d7c895362d0c",
  • "location_id": "46910cc3-ab41-4b80-b4a7-94dab9f1b795",
  • "amount": {
    },
  • "line_items": [
    ],
  • "purchase_order_task_id": "7c776152-0a17-416d-a60e-8bb19184c771",
  • "vendor_bill_number": "string",
  • "bill_number": "string",
  • "bill_date": "2019-08-24",
  • "notes": "string",
  • "priority": "high",
  • "due_at": "2019-08-24T14:15:22Z",
  • "assigned_to_member_id": "f762546b-4e22-4cbc-845d-0a241ae61391"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Delete a bill

Authorizations:
apiKeyAuth
path Parameters
billId
required
string <uuid>

Responses

Move a bill to a different workflow stage

Thin wrapper over the task workflow-stage endpoint (same approval/condition rules apply, see /tasks/{taskId}/workflow_stages). A bill has no separate status field — its current workflow stage (Pending Approval / Approved / Cleared) is its status. Entering the stage the entity's system "cleared" event is bound to fires that event (defaults to the "Cleared" stage, but is user-configurable via the entity's workflow template events).

Authorizations:
apiKeyAuth
path Parameters
billId
required
string <uuid>
Request Body schema: application/json
required
workflow_template_stage_id
required
string <uuid>
planned_start_at
string <date-time>
planned_end_at
string <date-time>
actual_start_at
string <date-time>
bypass_approvals
boolean

Requires the bill.stage.bypass_approval permission.

Responses

Request samples

Content type
application/json
{
  • "workflow_template_stage_id": "79ea45b2-4be3-4980-a12d-3fd314348625",
  • "planned_start_at": "2019-08-24T14:15:22Z",
  • "planned_end_at": "2019-08-24T14:15:22Z",
  • "actual_start_at": "2019-08-24T14:15:22Z",
  • "bypass_approvals": true
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Flag a bill

Authorizations:
apiKeyAuth
path Parameters
billId
required
string <uuid>
Request Body schema: application/json
reason
string or null

Responses

Request samples

Content type
application/json
{
  • "reason": "string"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Remove the flag from a bill

Authorizations:
apiKeyAuth
path Parameters
billId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Materials

List materials

Authorizations:
apiKeyAuth
query Parameters
filter
string

key operator value filter convention. Supported keys: name, sku, category, usage_type, is_active.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Create a material

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
name
required
string
sku
string or null
base_unit
required
string
category
string or null
reorder_point
number or null
usage_type
string
Default: "consumable"
Enum: "consumable" "reusable"

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "sku": "string",
  • "base_unit": "string",
  • "category": "string",
  • "reorder_point": 0,
  • "usage_type": "consumable"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get a material

Authorizations:
apiKeyAuth
path Parameters
materialId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update a material

Authorizations:
apiKeyAuth
path Parameters
materialId
required
string <uuid>
Request Body schema: application/json
name
required
string
sku
string or null
base_unit
required
string
category
string or null
reorder_point
number or null
usage_type
string
Default: "consumable"
Enum: "consumable" "reusable"
is_active
boolean

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "sku": "string",
  • "base_unit": "string",
  • "category": "string",
  • "reorder_point": 0,
  • "usage_type": "consumable",
  • "is_active": true
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Archive a material

Soft delete -- sets is_active to false. Materials are referenced by the stock ledger (RESTRICT), so they are never hard-deleted.

Authorizations:
apiKeyAuth
path Parameters
materialId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

List a material's purchase units

Authorizations:
apiKeyAuth
path Parameters
materialId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Add a purchase unit to a material

A material can have any number of purchase units, each with its own conversion_factor. unit must differ from the material's base_unit and be unique for this material.

Authorizations:
apiKeyAuth
path Parameters
materialId
required
string <uuid>
Request Body schema: application/json
required
unit
required
string

Must differ from the material's base_unit, and be unique per material.

conversion_factor
required
number

Must be > 0.

Responses

Request samples

Content type
application/json
{
  • "unit": "string",
  • "conversion_factor": 0
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update a material's purchase unit

Authorizations:
apiKeyAuth
path Parameters
materialId
required
string <uuid>
purchaseUnitId
required
string <uuid>
Request Body schema: application/json
unit
required
string

Must differ from the material's base_unit, and be unique per material.

conversion_factor
required
number

Must be > 0.

Responses

Request samples

Content type
application/json
{
  • "unit": "string",
  • "conversion_factor": 0
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Remove a purchase unit from a material

Line items that already reference this unit string are unaffected (they store the unit as plain text, not a foreign key) -- but new PO/Delivery line items can no longer use it.

Authorizations:
apiKeyAuth
path Parameters
materialId
required
string <uuid>
purchaseUnitId
required
string <uuid>

Responses

Automations

List automations

Requires a paid plan (AccountPlan.is_paid) -- see the note on POST /automations.

Authorizations:
apiKeyAuth
query Parameters
entity_type
string

Filter to automations targeting this entity_type.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Create an automation

The whole Automations API is a paid-plan feature (AccountPlan.is_paid) -- enforced for every session type, including the normal in-app cookie session, not just programmatic (API key/MCP) access.

Validated against the account's actual data, not just shape: entity_type must have an existing workflow template, trigger_config.workflow_template_stage_id (for stage_entered) must be a real stage on it, action types/resources/operations must be ones this API supports, and conditions must reference real task fields or custom fields with operators valid for their data type.

entity_type "booking" is validated differently (see AutomationInput.entity_type): no workflow-template lookup, trigger_type must be booking_status_changed, actions must be generate_booking_operational_tasks, and conditions are rejected outright rather than silently accepted-but-never-evaluated.

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
name
required
string
entity_type
required
string

Must have an existing entity + workflow template on this account (these are created lazily, e.g. by the first delivery/PO/deal/maintenance-request/housekeeping-task) -- except "booking", which is special-cased: Booking has no Entity/EntityWorkflowTemplate (it's deliberately not Task-backed), so that lookup is skipped entirely for it. entity_type "booking" only supports trigger_type "booking_status_changed", only the generate_booking_operational_tasks action, and does not support conditions yet (see AutomationTriggerType/AutomationAction). Immutable after creation.

trigger_type
required
string (AutomationTriggerType)
Enum: "stage_entered" "task_created" "task_updated" "task_deleted" "form_response_submitted" "booking_status_changed"

The first four are Task-lifecycle triggers, evaluated for any Task-backed entity_type. The last two are special-cased:

  • form_response_submitted fires when a FormResponse is submitted against a task via POST /forms/{form_id}/responses (not the public/anonymous form submission endpoint, which never links to a resource). The dispatched snapshot is the task's plain fields with the response's field values spread on top as flat keys, so a condition can reference a form field by its id via field_source: task_field, with no new condition machinery.
  • booking_status_changed is entity_type "booking" only. Booking is not Task-backed, so this trigger doesn't go through the Task-lifecycle machinery at all -- see AutomationInput.entity_type and AutomationAction.type for what's different (no Entity/workflow-template requirement, a separate synchronous action registry, no conditions support yet).
object

Required workflow_template_stage_id (a real stage on entity_type's workflow template) for stage_entered triggers; optional { form_id } for form_response_submitted; optional { to_status } (a BookingStatus value) for booking_status_changed; omit for task_created/task_updated/task_deleted.

(AutomationConditionGroup (object or null)) or (AutomationConditionRule (object or null))

Not supported for entity_type "booking" -- omit, or the request is rejected with a 400.

required
Array of objects (AutomationAction) non-empty
enabled
boolean
Default: true

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "entity_type": "string",
  • "trigger_type": "stage_entered",
  • "trigger_config": { },
  • "conditions": {
    },
  • "actions": [
    ],
  • "enabled": true
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get an automation

Authorizations:
apiKeyAuth
path Parameters
automationId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update an automation

entity_type cannot be changed after creation -- create a new automation instead. System automations (is_system) can be updated/disabled like any other.

Authorizations:
apiKeyAuth
path Parameters
automationId
required
string <uuid>
Request Body schema: application/json
name
string
object
(AutomationConditionGroup (object or null)) or (AutomationConditionRule (object or null))

A node is either a condition group (logic + rules, up to 5 levels deep) or a single rule (field_source + operator) -- never both.

Array of objects (AutomationAction) non-empty
enabled
boolean

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "trigger_config": { },
  • "conditions": {
    },
  • "actions": [
    ],
  • "enabled": true
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Delete an automation

System automations (is_system) can be deleted like any other -- but note a deleted one may reappear the next time its underlying entity is lazily re-seeded (e.g. the next delivery created triggers the delivery-automation seed check again). Use PATCH { enabled: false } instead if you want the change to stick.

Authorizations:
apiKeyAuth
path Parameters
automationId
required
string <uuid>

Responses

List an automation's run log

Ordered ran_at desc. This is how to answer "did this automation fire, and what happened" -- pending/processing/success/failed/skipped runs are all recorded here. One row per action, not per firing -- an automation with N actions produces N rows per trigger event, correlated by AutomationRun.trigger_group_id (a "skipped" row, with action_type null, is the exception: one row for the whole automation when conditions didn't pass or the hop depth was exceeded).

Authorizations:
apiKeyAuth
path Parameters
automationId
required
string <uuid>
query Parameters
limit
integer
Default: 50
offset
integer
Default: 0

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Locations

List locations

Flat list of the account's locations. Use parent_id to reconstruct the location breakdown structure client-side.

Authorizations:
apiKeyAuth
query Parameters
filter
string

key operator value filter convention. Supported keys: name, parent_id, type, is_active.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Create a location

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
name
required
string
parent_id
string or null <uuid>
latitude
number or null <float>
longitude
number or null <float>
type
string or null

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "parent_id": "1c6ca187-e61f-4301-8dcb-0e9749e89eef",
  • "latitude": 0.1,
  • "longitude": 0.1,
  • "type": "string"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get a location

Authorizations:
apiKeyAuth
path Parameters
locationId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update a location

Authorizations:
apiKeyAuth
path Parameters
locationId
required
string <uuid>
Request Body schema: application/json
name
required
string
parent_id
string or null <uuid>
latitude
number or null <float>
longitude
number or null <float>
type
string or null
is_active
boolean

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "parent_id": "1c6ca187-e61f-4301-8dcb-0e9749e89eef",
  • "latitude": 0.1,
  • "longitude": 0.1,
  • "type": "string",
  • "is_active": true
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Archive a location

Soft delete -- sets is_active to false. Locations are referenced by the stock ledger (RESTRICT) and by child locations.

Authorizations:
apiKeyAuth
path Parameters
locationId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

StockTransactions

List stock transactions

The raw inventory ledger. Order is transaction_at desc, then created_at desc. Each row's reference_type/reference_id is hydrated into a reference object -- see StockTransaction.reference for the shape per reference_type (e.g. a "delivery" reference includes its purchase_order, purchase_requisition, and vendor).

Authorizations:
apiKeyAuth
query Parameters
filter
string

key operator value filter convention. Supported keys: material_id, location_id, type, transaction_at, reference_type, reference_id.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Post a manual stock transaction

Any StockTransaction type can be posted here -- no type is restricted from manual creation, and no type is restricted by the material's usage_type (e.g. ISSUE/RETURN_TO_STORE and CONSUMPTION can both be posted for reusable or consumable materials alike). Set reference_type/reference_id (e.g. "task" + a task id) to record what an ISSUE or CONSUMPTION was for; leave them null for ad-hoc postings not tied to a specific task. Any posting that would take a material/location combo negative is rejected unless the account's preferences.allow_negative_stock is true. Note: RECEIPT rows are also posted automatically (asynchronously, within about a minute) by the system Automation on the Delivery "Verified" stage (tagged reference_type=delivery) -- see GET /automations -- posting RECEIPT here manually for the same delivery would double-count.

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
material_id
required
string <uuid>
location_id
string or null <uuid>
type
required
string
Enum: "OPENING_BALANCE" "RECEIPT" "ISSUE" "CONSUMPTION" "ADJUSTMENT_IN" "ADJUSTMENT_OUT" "WASTAGE" "TRANSFER_IN" "TRANSFER_OUT" "RETURN_TO_SUPPLIER" "RETURN_TO_STORE"

Any type can be posted here, including RECEIPT -- but the Delivery "Verified" stage action also auto-posts RECEIPT rows (reference_type=delivery), so only post RECEIPT manually for stock that didn't arrive through a Delivery, to avoid double-counting. Not restricted by the material's usage_type: ISSUE (out, expected back -- pair with RETURN_TO_STORE) and CONSUMPTION (out, permanently used up) can both be posted for any material.

purchase_unit
string or null

Must resolve to the material's base_unit or one of its configured purchase units. Required together with purchase_quantity; omit both to enter base_quantity directly instead.

purchase_quantity
number or null

Denominated in purchase_unit. Required if purchase_unit is given.

purchase_rate
number or null

Price per purchase_unit.

base_quantity
number

Denominated in the material's base_unit. Required if purchase_unit is not given.

base_rate
number or null

Price per base_unit.

currency
string or null
transaction_at
required
string <date-time>
reference_type
string or null

e.g. "task", to record what an ISSUE or CONSUMPTION was for. Optional -- ad-hoc postings can leave this null.

reference_id
string or null <uuid>
reason
string or null
note
string or null

Responses

Request samples

Content type
application/json
{
  • "material_id": "fba2a54e-bc4a-4e2a-8ad4-84dcfe66dea1",
  • "location_id": "46910cc3-ab41-4b80-b4a7-94dab9f1b795",
  • "type": "OPENING_BALANCE",
  • "purchase_unit": "string",
  • "purchase_quantity": 0,
  • "purchase_rate": 0,
  • "base_quantity": 0,
  • "base_rate": 0,
  • "currency": "string",
  • "transaction_at": "2019-08-24T14:15:22Z",
  • "reference_type": "string",
  • "reference_id": "97c1ff22-6e4f-4821-b1d3-5236781d37b8",
  • "reason": "string",
  • "note": "string"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get current stock, aggregated by material and location

Returns SUM(base_quantity) grouped by material_id + location_id. No daily snapshot table -- always derived from the ledger.

Authorizations:
apiKeyAuth
query Parameters
filter
string

key operator value filter convention. Supported keys: material_id, location_id.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Get a stock transaction

Authorizations:
apiKeyAuth
path Parameters
stockTransactionId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

PurchaseRequisitions

List purchase requisitions

Lists tasks joined with their purchase_requisition_detail. Purchase requisitions all live in the account's single, lazily provisioned "Purchase Requisitions" entity (workflow stages Requested -> Approved -> Partially Ordered -> Ordered -> Partially Received -> Fulfilled). Once a purchase requisition is Approved, "Partially Ordered"/"Ordered"/"Partially Received"/"Fulfilled" are moved into automatically by the update_purchase_requisition_progress automation (see AutomationAction) as purchase orders raised against it are acknowledged and their deliveries are received -- see POST /purchase-orders/{purchaseOrderId}/stage. Accounts that skip purchase orders entirely can instead link a delivery straight to the purchase requisition (Delivery's purchase_requisition_task_id) -- the same automation then moves the PR directly from Approved to "Partially Received"/"Fulfilled" (skipping the ordering stages, since there's no PO) as those deliveries are received -- see POST /deliveries/{deliveryId}/stage.

Authorizations:
apiKeyAuth
query Parameters
filter
string

key operator value filter convention. Supported keys: title, priority, due_at, assigned_to_member_id, participant_member_id, created_at, id (Task fields), material_id (matches purchase requisitions with at least one line item for the given material_id -- eq/in/ne only), current_stage_id (matches the workflow_template_stage_id of the purchase requisition's current (latest) workflow stage -- eq/in/ne only), and location_id, pr_number, created_by_member_id (purchase_requisition_detail fields).

limit
integer <= 100
Default: 20
offset
integer
Default: 0

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Create a purchase requisition

Creates a Task in the account's Purchase Requisitions entity (plus its purchase_requisition_detail row), lazily provisioning the entity and its workflow on first use. pr_number, if omitted, is auto-generated from the account's current purchase requisition numbering settings (see /purchase-requisitions/settings/numbering) and is snapshotted at creation time -- later prefix/counter changes never retroactively affect already-created purchase requisitions.

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
title
required
string
description
string
location_id
string or null <uuid>

Must refer to a location owned by this account.

pr_number
string or null

Auto-generated from account settings if omitted; pass a value to override.

required
Array of objects (PurchaseRequisitionLineItem)
notes
string or null
priority
string (TaskPriority)
Enum: "high" "medium" "low"
due_at
string <date-time>
assigned_to_member_id
string <uuid>

Responses

Request samples

Content type
application/json
{
  • "title": "string",
  • "description": "string",
  • "location_id": "46910cc3-ab41-4b80-b4a7-94dab9f1b795",
  • "pr_number": "string",
  • "line_items": [
    ],
  • "notes": "string",
  • "priority": "high",
  • "due_at": "2019-08-24T14:15:22Z",
  • "assigned_to_member_id": "f762546b-4e22-4cbc-845d-0a241ae61391"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get the account's purchase requisition numbering settings

Authorizations:
apiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update the account's purchase requisition numbering prefix and/or reset the counter

A manual settings action -- purely a config write, never alters pr_number on already-created purchase requisitions.

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
prefix
string non-empty
reset_counter_to
integer >= 0

Responses

Request samples

Content type
application/json
{
  • "prefix": "string",
  • "reset_counter_to": 0
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get a purchase requisition

Authorizations:
apiKeyAuth
path Parameters
purchaseRequisitionId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update a purchase requisition

Authorizations:
apiKeyAuth
path Parameters
purchaseRequisitionId
required
string <uuid>
Request Body schema: application/json
title
required
string
description
string
location_id
string or null <uuid>

Must refer to a location owned by this account.

pr_number
string or null

Auto-generated from account settings if omitted; pass a value to override.

required
Array of objects (PurchaseRequisitionLineItem)
notes
string or null
priority
string (TaskPriority)
Enum: "high" "medium" "low"
due_at
string <date-time>
assigned_to_member_id
string <uuid>

Responses

Request samples

Content type
application/json
{
  • "title": "string",
  • "description": "string",
  • "location_id": "46910cc3-ab41-4b80-b4a7-94dab9f1b795",
  • "pr_number": "string",
  • "line_items": [
    ],
  • "notes": "string",
  • "priority": "high",
  • "due_at": "2019-08-24T14:15:22Z",
  • "assigned_to_member_id": "f762546b-4e22-4cbc-845d-0a241ae61391"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Delete a purchase requisition

Authorizations:
apiKeyAuth
path Parameters
purchaseRequisitionId
required
string <uuid>

Responses

Move a purchase requisition to a different workflow stage

Thin wrapper over the task workflow-stage endpoint (same approval/condition rules apply).

Authorizations:
apiKeyAuth
path Parameters
purchaseRequisitionId
required
string <uuid>
Request Body schema: application/json
required
workflow_template_stage_id
required
string <uuid>
planned_start_at
string <date-time>
planned_end_at
string <date-time>
actual_start_at
string <date-time>
bypass_approvals
boolean

Requires the purchase_requisition.stage.bypass_approval permission.

Responses

Request samples

Content type
application/json
{
  • "workflow_template_stage_id": "79ea45b2-4be3-4980-a12d-3fd314348625",
  • "planned_start_at": "2019-08-24T14:15:22Z",
  • "planned_end_at": "2019-08-24T14:15:22Z",
  • "actual_start_at": "2019-08-24T14:15:22Z",
  • "bypass_approvals": true
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

PurchaseOrders

List purchase orders

Lists tasks joined with their purchase_order_detail and vendor. Purchase orders all live in the account's single, lazily provisioned "Purchase Orders" entity (workflow stages Draft -> Sent -> Acknowledged -> Partially Received -> Fulfilled).

Authorizations:
apiKeyAuth
query Parameters
filter
string

key operator value filter convention. Supported keys: title, priority, due_at, assigned_to_member_id, participant_member_id, created_at, id (Task fields), material_id (matches purchase orders with at least one line item for the given material_id -- eq/in/ne only), current_stage_id (matches the workflow_template_stage_id of the purchase order's current (latest) workflow stage -- eq/in/ne only), and vendor_id, location_id, purchase_requisition_task_id, po_number, created_by_member_id (purchase_order_detail fields).

limit
integer <= 100
Default: 20
offset
integer
Default: 0

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Create a purchase order

Creates a Task in the account's Purchase Orders entity (plus its purchase_order_detail row), lazily provisioning the entity and its workflow on first use. purchase_requisition_task_id, if given, must refer to a task owned by this account (not required to be a purchase requisition -- a PO does not strictly require a requisition). po_number, if omitted, is auto-generated from the account's current purchase order numbering settings (see /purchase-orders/settings/numbering) and is snapshotted at creation time -- later prefix/counter changes never retroactively affect already-created purchase orders.

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
title
required
string
description
string
vendor_id
string or null <uuid>
location_id
string or null <uuid>

Must refer to a location owned by this account.

purchase_requisition_task_id
string or null <uuid>
po_number
string or null

Auto-generated from account settings if omitted; pass a value to override.

required
Array of objects (PurchaseOrderLineItem)
expected_delivery_date
string or null <date>
notes
string or null
priority
string (TaskPriority)
Enum: "high" "medium" "low"
due_at
string <date-time>
assigned_to_member_id
string <uuid>

Responses

Request samples

Content type
application/json
{
  • "title": "string",
  • "description": "string",
  • "vendor_id": "98232994-9d54-43ee-a280-d7c895362d0c",
  • "location_id": "46910cc3-ab41-4b80-b4a7-94dab9f1b795",
  • "purchase_requisition_task_id": "ec4ba24c-4e87-4c37-acbe-d457bd07ae98",
  • "po_number": "string",
  • "line_items": [
    ],
  • "expected_delivery_date": "2019-08-24",
  • "notes": "string",
  • "priority": "high",
  • "due_at": "2019-08-24T14:15:22Z",
  • "assigned_to_member_id": "f762546b-4e22-4cbc-845d-0a241ae61391"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get the account's purchase order numbering settings

Authorizations:
apiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update the account's purchase order numbering prefix and/or reset the counter

A manual settings action -- purely a config write, never alters po_number on already-created purchase orders.

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
prefix
string non-empty
reset_counter_to
integer >= 0

Responses

Request samples

Content type
application/json
{
  • "prefix": "string",
  • "reset_counter_to": 0
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get a purchase order

Authorizations:
apiKeyAuth
path Parameters
purchaseOrderId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update a purchase order

Authorizations:
apiKeyAuth
path Parameters
purchaseOrderId
required
string <uuid>
Request Body schema: application/json
title
required
string
description
string
vendor_id
string or null <uuid>
location_id
string or null <uuid>

Must refer to a location owned by this account.

purchase_requisition_task_id
string or null <uuid>
po_number
string or null

Auto-generated from account settings if omitted; pass a value to override.

required
Array of objects (PurchaseOrderLineItem)
expected_delivery_date
string or null <date>
notes
string or null
priority
string (TaskPriority)
Enum: "high" "medium" "low"
due_at
string <date-time>
assigned_to_member_id
string <uuid>

Responses

Request samples

Content type
application/json
{
  • "title": "string",
  • "description": "string",
  • "vendor_id": "98232994-9d54-43ee-a280-d7c895362d0c",
  • "location_id": "46910cc3-ab41-4b80-b4a7-94dab9f1b795",
  • "purchase_requisition_task_id": "ec4ba24c-4e87-4c37-acbe-d457bd07ae98",
  • "po_number": "string",
  • "line_items": [
    ],
  • "expected_delivery_date": "2019-08-24",
  • "notes": "string",
  • "priority": "high",
  • "due_at": "2019-08-24T14:15:22Z",
  • "assigned_to_member_id": "f762546b-4e22-4cbc-845d-0a241ae61391"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Delete a purchase order

Authorizations:
apiKeyAuth
path Parameters
purchaseOrderId
required
string <uuid>

Responses

Move a purchase order to a different workflow stage

Thin wrapper over the task workflow-stage endpoint. Note: two system-bound transitions already happen automatically as a byproduct of other actions -- POST .../send moves a PO to "Sent", and an automation (see update_purchase_order_fulfillment in AutomationAction) auto-moves a linked PO to "Partially Received" / "Fulfilled" as its deliveries are marked delivered. This endpoint remains available for moving a PO to any stage manually (e.g. "Acknowledged" or "Cancelled"), same as Bill today. Moving a PO into "Acknowledged", "Partially Received", or "Fulfilled" (whether via this endpoint or the automated transitions above) also fires update_purchase_requisition_progress, which rolls the PO's linked purchase requisition (if any) forward through "Partially Ordered" / "Ordered" / "Partially Received" / "Fulfilled" based on the aggregate ordered/delivered quantities of every non-cancelled PO raised against it.

Authorizations:
apiKeyAuth
path Parameters
purchaseOrderId
required
string <uuid>
Request Body schema: application/json
required
workflow_template_stage_id
required
string <uuid>
planned_start_at
string <date-time>
planned_end_at
string <date-time>
actual_start_at
string <date-time>
bypass_approvals
boolean

Requires the purchase_order.stage.bypass_approval permission.

Responses

Request samples

Content type
application/json
{
  • "workflow_template_stage_id": "79ea45b2-4be3-4980-a12d-3fd314348625",
  • "planned_start_at": "2019-08-24T14:15:22Z",
  • "planned_end_at": "2019-08-24T14:15:22Z",
  • "actual_start_at": "2019-08-24T14:15:22Z",
  • "bypass_approvals": true
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Deliveries

List deliveries

Lists tasks joined with their delivery_detail. Deliveries all live in the account's single, lazily provisioned "Deliveries" entity (workflow stages Planned -> Expected -> Received -> Verified -> Closed).

Authorizations:
apiKeyAuth
query Parameters
filter
string

key operator value filter convention. Supported keys: title, priority, due_at, assigned_to_member_id, participant_member_id, created_at, id (Task fields), material_id (matches deliveries with at least one line item for the given material_id -- eq/in/ne only), current_stage_id (matches the workflow_template_stage_id of the delivery's current (latest) workflow stage -- eq/in/ne only), and purchase_order_task_id, purchase_requisition_task_id, vendor_id, delivery_number, created_by_member_id (delivery_detail fields).

limit
integer <= 100
Default: 20
offset
integer
Default: 0

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Create a delivery

Creates a Task in the account's Deliveries entity (plus its delivery_detail row), lazily provisioning the entity and its workflow on first use. purchase_order_task_id and purchase_requisition_task_id are both optional and mutually exclusive -- set at most one, to link this delivery either to a Purchase Order or, for accounts that skip POs entirely, directly to a Purchase Requisition; whichever is given must refer to a task owned by this account. For deliveries with no purchase order, vendor_id/amount can be set directly on the delivery instead -- e.g. so a "create bill on stage change" automation has a vendor and amount to read. delivery_number, if omitted, is auto-generated from the account's current delivery numbering settings (see /deliveries/settings/numbering) and is snapshotted at creation time -- later prefix/counter changes never retroactively affect already-created deliveries.

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
title
required
string
description
string
purchase_order_task_id
string or null <uuid>

Optional link to the Purchase Order this delivery fulfills. Mutually exclusive with purchase_requisition_task_id.

purchase_requisition_task_id
string or null <uuid>

Optional direct link to the Purchase Requisition this delivery fulfills, for accounts that skip Purchase Orders entirely. Mutually exclusive with purchase_order_task_id -- setting both is rejected.

vendor_id
string or null <uuid>

For deliveries with no purchase_order_task_id, since a PO-linked delivery's vendor is derived from the PO. Must refer to a vendor owned by this account.

object (Money)
delivery_number
string or null

Auto-generated from account settings if omitted; pass a value to override.

required
Array of objects (DeliveryLineItem)
notes
string or null
priority
string (TaskPriority)
Enum: "high" "medium" "low"
due_at
string <date-time>
assigned_to_member_id
string <uuid>

Responses

Request samples

Content type
application/json
{
  • "title": "string",
  • "description": "string",
  • "purchase_order_task_id": "7c776152-0a17-416d-a60e-8bb19184c771",
  • "purchase_requisition_task_id": "ec4ba24c-4e87-4c37-acbe-d457bd07ae98",
  • "vendor_id": "98232994-9d54-43ee-a280-d7c895362d0c",
  • "amount": {
    },
  • "delivery_number": "string",
  • "line_items": [
    ],
  • "notes": "string",
  • "priority": "high",
  • "due_at": "2019-08-24T14:15:22Z",
  • "assigned_to_member_id": "f762546b-4e22-4cbc-845d-0a241ae61391"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get the account's delivery numbering settings

Authorizations:
apiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update the account's delivery numbering prefix and/or reset the counter

A manual settings action -- purely a config write, never alters delivery_number on already-created deliveries.

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
prefix
string non-empty
reset_counter_to
integer >= 0

Responses

Request samples

Content type
application/json
{
  • "prefix": "string",
  • "reset_counter_to": 0
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get a delivery

Authorizations:
apiKeyAuth
path Parameters
deliveryId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update a delivery

Authorizations:
apiKeyAuth
path Parameters
deliveryId
required
string <uuid>
Request Body schema: application/json
title
required
string
description
string
purchase_order_task_id
string or null <uuid>

Optional link to the Purchase Order this delivery fulfills. Mutually exclusive with purchase_requisition_task_id.

purchase_requisition_task_id
string or null <uuid>

Optional direct link to the Purchase Requisition this delivery fulfills, for accounts that skip Purchase Orders entirely. Mutually exclusive with purchase_order_task_id -- setting both is rejected.

vendor_id
string or null <uuid>

For deliveries with no purchase_order_task_id, since a PO-linked delivery's vendor is derived from the PO. Must refer to a vendor owned by this account.

object (Money)
delivery_number
string or null

Auto-generated from account settings if omitted; pass a value to override.

required
Array of objects (DeliveryLineItem)
notes
string or null
priority
string (TaskPriority)
Enum: "high" "medium" "low"
due_at
string <date-time>
assigned_to_member_id
string <uuid>

Responses

Request samples

Content type
application/json
{
  • "title": "string",
  • "description": "string",
  • "purchase_order_task_id": "7c776152-0a17-416d-a60e-8bb19184c771",
  • "purchase_requisition_task_id": "ec4ba24c-4e87-4c37-acbe-d457bd07ae98",
  • "vendor_id": "98232994-9d54-43ee-a280-d7c895362d0c",
  • "amount": {
    },
  • "delivery_number": "string",
  • "line_items": [
    ],
  • "notes": "string",
  • "priority": "high",
  • "due_at": "2019-08-24T14:15:22Z",
  • "assigned_to_member_id": "f762546b-4e22-4cbc-845d-0a241ae61391"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Delete a delivery

Authorizations:
apiKeyAuth
path Parameters
deliveryId
required
string <uuid>

Responses

Move a delivery to a different workflow stage

Thin wrapper over the task workflow-stage endpoint. Moving into the stage configured with the create_stock_receipt action (currently "Verified") automatically posts one RECEIPT StockTransaction per delivery_detail line item, in the same transaction. This is idempotent -- re-entering the stage will not double-post -- and the stage/action mapping is data (EntityWorkflowTemplateStage.actions), not hardcoded, so it can be reassigned to a different stage later without a code change.

Authorizations:
apiKeyAuth
path Parameters
deliveryId
required
string <uuid>
Request Body schema: application/json
required
workflow_template_stage_id
required
string <uuid>
planned_start_at
string <date-time>
planned_end_at
string <date-time>
actual_start_at
string <date-time>
bypass_approvals
boolean

Requires the delivery.stage.bypass_approval permission.

Responses

Request samples

Content type
application/json
{
  • "workflow_template_stage_id": "79ea45b2-4be3-4980-a12d-3fd314348625",
  • "planned_start_at": "2019-08-24T14:15:22Z",
  • "planned_end_at": "2019-08-24T14:15:22Z",
  • "actual_start_at": "2019-08-24T14:15:22Z",
  • "bypass_approvals": true
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Assets

List assets

The account's equipment/facility register, nested under Location.

Authorizations:
apiKeyAuth
query Parameters
filter
string

key operator value filter convention. Supported keys: name, location_id, category, status, criticality.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Create an asset

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
name
required
string
location_id
required
string <uuid>

Must refer to a location owned by this account.

category
required
string (AssetCategory)
Enum: "hvac" "electrical" "plumbing" "generator" "lift" "av_equipment" "furniture" "fire_safety" "other"
serial_number
string or null
model
string or null
manufacturer
string or null
purchase_date
string or null <date>
warranty_expires_at
string or null <date>
status
string (AssetStatus)
Default: "active"
Enum: "active" "under_maintenance" "retired"
criticality
string (AssetCriticality)
Default: "medium"
Enum: "low" "medium" "high"

Informational today -- intended to drive future SLA/escalation defaults for maintenance requests against this asset.

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "location_id": "46910cc3-ab41-4b80-b4a7-94dab9f1b795",
  • "category": "hvac",
  • "serial_number": "string",
  • "model": "string",
  • "manufacturer": "string",
  • "purchase_date": "2019-08-24",
  • "warranty_expires_at": "2019-08-24",
  • "status": "active",
  • "criticality": "low"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get an asset

Authorizations:
apiKeyAuth
path Parameters
assetId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update an asset

Authorizations:
apiKeyAuth
path Parameters
assetId
required
string <uuid>
Request Body schema: application/json
name
string
location_id
string <uuid>
category
string (AssetCategory)
Enum: "hvac" "electrical" "plumbing" "generator" "lift" "av_equipment" "furniture" "fire_safety" "other"
serial_number
string or null
model
string or null
manufacturer
string or null
purchase_date
string or null <date>
warranty_expires_at
string or null <date>
status
string (AssetStatus)
Default: "active"
Enum: "active" "under_maintenance" "retired"
criticality
string (AssetCriticality)
Default: "medium"
Enum: "low" "medium" "high"

Informational today -- intended to drive future SLA/escalation defaults for maintenance requests against this asset.

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "location_id": "46910cc3-ab41-4b80-b4a7-94dab9f1b795",
  • "category": "hvac",
  • "serial_number": "string",
  • "model": "string",
  • "manufacturer": "string",
  • "purchase_date": "2019-08-24",
  • "warranty_expires_at": "2019-08-24",
  • "status": "active",
  • "criticality": "low"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Retire an asset

Soft delete -- sets status to "retired" rather than removing the row, since assets are referenced by maintenance request history.

Authorizations:
apiKeyAuth
path Parameters
assetId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

MaintenanceRequests

List maintenance requests

Lists tasks joined with their maintenance_request_detail. Maintenance requests all live in the account's single, automatically provisioned "Maintenance Requests" entity (workflow Reported -> Assigned -> In Progress -> Resolved -> Cancelled).

Authorizations:
apiKeyAuth
query Parameters
filter
string

key operator value filter convention. Supported keys: title, priority, due_at, assigned_to_member_id, participant_member_id, created_at, id, current_stage_id (Task fields), and asset_id, location_id, maintenance_request_number, request_type, severity, created_by_member_id (maintenance_request_detail fields).

limit
integer <= 100
Default: 20
offset
integer
Default: 0

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Create a maintenance request

Creates a Task in the account's Maintenance Requests entity (plus its maintenance_request_detail row). Either asset_id or location_id must be provided -- area-level requests (e.g. "washroom inspection") use location_id instead of a specific asset. maintenance_request_number, if omitted, is auto-generated from the account's current maintenance request numbering settings (see /maintenance-requests/settings/numbering) and is snapshotted at creation time.

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
title
required
string
description
string
asset_id
string or null <uuid>

Either asset_id or location_id must be provided.

location_id
string or null <uuid>
maintenance_request_number
string or null

Auto-generated from account settings if omitted; pass a value to override.

request_type
required
string (MaintenanceRequestType)
Enum: "breakdown" "complaint" "preventive" "inspection"
severity
string (MaintenanceRequestSeverity)
Default: "medium"
Enum: "low" "medium" "high" "critical"
reported_by_member_id
string or null <uuid>
reported_by_customer_id
string or null <uuid>
sop_template_id
string or null <uuid>

Must refer to an SOP template owned by this account.

priority
string (TaskPriority)
Enum: "high" "medium" "low"
due_at
string <date-time>
assigned_to_member_id
string <uuid>

Responses

Request samples

Content type
application/json
{
  • "title": "string",
  • "description": "string",
  • "asset_id": "b4695157-0d1d-4da0-8f9e-5c53149389e4",
  • "location_id": "46910cc3-ab41-4b80-b4a7-94dab9f1b795",
  • "maintenance_request_number": "string",
  • "request_type": "breakdown",
  • "severity": "low",
  • "reported_by_member_id": "356a03fa-2868-4675-8be7-f0389d4767d8",
  • "reported_by_customer_id": "48689b84-0d51-4ccd-a902-c6c1dbebeec7",
  • "sop_template_id": "509744fe-18db-4787-b961-91e337a8f6aa",
  • "priority": "high",
  • "due_at": "2019-08-24T14:15:22Z",
  • "assigned_to_member_id": "f762546b-4e22-4cbc-845d-0a241ae61391"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get the account's maintenance request numbering settings

Authorizations:
apiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update the account's maintenance request numbering prefix and/or reset the counter

A manual settings action -- purely a config write, never alters maintenance_request_number on already-created maintenance requests.

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
prefix
string non-empty
reset_counter_to
integer >= 0

Responses

Request samples

Content type
application/json
{
  • "prefix": "string",
  • "reset_counter_to": 0
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get a maintenance request

Authorizations:
apiKeyAuth
path Parameters
maintenanceRequestId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update a maintenance request

Updates Task fields (title, description, priority, due_at, assigned_to_member_id) and/or maintenance_request_detail fields. Workflow stage transitions go through POST .../stage; comments and attachments go through the Tasks API (/tasks/{taskId}/...), not this endpoint.

Authorizations:
apiKeyAuth
path Parameters
maintenanceRequestId
required
string <uuid>
Request Body schema: application/json
title
string
description
string
asset_id
string or null <uuid>
location_id
string or null <uuid>
maintenance_request_number
string or null

Auto-generated from account settings if omitted; pass a value to override.

request_type
string (MaintenanceRequestType)
Enum: "breakdown" "complaint" "preventive" "inspection"
severity
string (MaintenanceRequestSeverity)
Default: "medium"
Enum: "low" "medium" "high" "critical"
sop_template_id
string or null <uuid>
resolution_notes
string or null
resolved_at
string or null <date-time>
priority
string (TaskPriority)
Enum: "high" "medium" "low"
due_at
string <date-time>
assigned_to_member_id
string <uuid>

Responses

Request samples

Content type
application/json
{
  • "title": "string",
  • "description": "string",
  • "asset_id": "b4695157-0d1d-4da0-8f9e-5c53149389e4",
  • "location_id": "46910cc3-ab41-4b80-b4a7-94dab9f1b795",
  • "maintenance_request_number": "string",
  • "request_type": "breakdown",
  • "severity": "low",
  • "sop_template_id": "509744fe-18db-4787-b961-91e337a8f6aa",
  • "resolution_notes": "string",
  • "resolved_at": "2019-08-24T14:15:22Z",
  • "priority": "high",
  • "due_at": "2019-08-24T14:15:22Z",
  • "assigned_to_member_id": "f762546b-4e22-4cbc-845d-0a241ae61391"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Delete a maintenance request

Authorizations:
apiKeyAuth
path Parameters
maintenanceRequestId
required
string <uuid>

Responses

Move a maintenance request to a different workflow stage

Thin wrapper over the task workflow-stage endpoint (same approval/condition rules apply).

Authorizations:
apiKeyAuth
path Parameters
maintenanceRequestId
required
string <uuid>
Request Body schema: application/json
required
workflow_template_stage_id
required
string <uuid>
planned_start_at
string <date-time>
planned_end_at
string <date-time>
actual_start_at
string <date-time>
bypass_approvals
boolean

Requires the maintenance_request.stage.bypass_approval permission.

Responses

Request samples

Content type
application/json
{
  • "workflow_template_stage_id": "79ea45b2-4be3-4980-a12d-3fd314348625",
  • "planned_start_at": "2019-08-24T14:15:22Z",
  • "planned_end_at": "2019-08-24T14:15:22Z",
  • "actual_start_at": "2019-08-24T14:15:22Z",
  • "bypass_approvals": true
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Edit planned dates, estimates, or progress on a specific workflow stage instance

Thin wrapper over the task workflow-stage-details endpoint. Unlike POST .../stage, this does not move the maintenance request to a different stage -- it edits metadata on a stage instance already in workflow_stages or still planned in next_workflow_stages.

Authorizations:
apiKeyAuth
path Parameters
maintenanceRequestId
required
string <uuid>
taskWorkflowStageId
required
string <uuid>

The id of a specific TaskWorkflowStage instance (not a workflow_template_stage_id) -- either an already-entered stage (current or a past visit) or a still-planned one from next_workflow_stages.

Request Body schema: application/json
required
planned_start_at
string or null <date-time>
planned_end_at
string or null <date-time>
estimated_duration_value
number or null

Must be provided together with estimated_duration_unit.

estimated_duration_unit
string or null
Enum: "hours" "days"
progress
integer [ 0 .. 100 ]

Responses

Request samples

Content type
application/json
{
  • "planned_start_at": "2019-08-24T14:15:22Z",
  • "planned_end_at": "2019-08-24T14:15:22Z",
  • "estimated_duration_value": 0,
  • "estimated_duration_unit": "hours",
  • "progress": 100
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

HousekeepingTasks

List housekeeping tasks

Lists tasks joined with their housekeeping_task_detail. Housekeeping tasks all live in the account's single, automatically provisioned "Housekeeping Tasks" entity (workflow Scheduled -> In Progress -> Completed -> Skipped).

Authorizations:
apiKeyAuth
query Parameters
filter
string

key operator value filter convention. Supported keys: title, priority, due_at, assigned_to_member_id, participant_member_id, created_at, id, current_stage_id (Task fields), and location_id, housekeeping_task_number, booking_id, scheduled_for, created_by_member_id (housekeeping_task_detail fields).

limit
integer <= 100
Default: 20
offset
integer
Default: 0

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Create a housekeeping task

Creates a Task in the account's Housekeeping Tasks entity (plus its housekeeping_task_detail row). housekeeping_task_number, if omitted, is auto-generated from the account's current housekeeping task numbering settings (see /housekeeping-tasks/settings/numbering) and is snapshotted at creation time.

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
title
required
string
description
string
location_id
required
string <uuid>

Must refer to a location owned by this account.

housekeeping_task_number
string or null

Auto-generated from account settings if omitted; pass a value to override.

checklist_form_id
string or null <uuid>
scheduled_for
required
string <date>
booking_id
string or null <uuid>
priority
string (TaskPriority)
Enum: "high" "medium" "low"
due_at
string <date-time>
assigned_to_member_id
string <uuid>

Responses

Request samples

Content type
application/json
{
  • "title": "string",
  • "description": "string",
  • "location_id": "46910cc3-ab41-4b80-b4a7-94dab9f1b795",
  • "housekeeping_task_number": "string",
  • "checklist_form_id": "13afa894-affb-4c23-8535-50b1cd054451",
  • "scheduled_for": "2019-08-24",
  • "booking_id": "b0ae0641-0cd4-4f7f-8550-dcd550941f4a",
  • "priority": "high",
  • "due_at": "2019-08-24T14:15:22Z",
  • "assigned_to_member_id": "f762546b-4e22-4cbc-845d-0a241ae61391"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get the account's housekeeping task numbering settings

Authorizations:
apiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update the account's housekeeping task numbering prefix and/or reset the counter

A manual settings action -- purely a config write, never alters housekeeping_task_number on already-created housekeeping tasks.

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
prefix
string non-empty
reset_counter_to
integer >= 0

Responses

Request samples

Content type
application/json
{
  • "prefix": "string",
  • "reset_counter_to": 0
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get a housekeeping task

Authorizations:
apiKeyAuth
path Parameters
housekeepingTaskId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update a housekeeping task

Updates Task fields (title, description, priority, due_at, assigned_to_member_id) and/or housekeeping_task_detail fields. Workflow stage transitions go through POST .../stage; comments and attachments go through the Tasks API (/tasks/{taskId}/...), not this endpoint.

Authorizations:
apiKeyAuth
path Parameters
housekeepingTaskId
required
string <uuid>
Request Body schema: application/json
title
string
description
string
location_id
string <uuid>
housekeeping_task_number
string or null

Auto-generated from account settings if omitted; pass a value to override.

checklist_form_id
string or null <uuid>
scheduled_for
string <date>
booking_id
string or null <uuid>
priority
string (TaskPriority)
Enum: "high" "medium" "low"
due_at
string <date-time>
assigned_to_member_id
string <uuid>

Responses

Request samples

Content type
application/json
{
  • "title": "string",
  • "description": "string",
  • "location_id": "46910cc3-ab41-4b80-b4a7-94dab9f1b795",
  • "housekeeping_task_number": "string",
  • "checklist_form_id": "13afa894-affb-4c23-8535-50b1cd054451",
  • "scheduled_for": "2019-08-24",
  • "booking_id": "b0ae0641-0cd4-4f7f-8550-dcd550941f4a",
  • "priority": "high",
  • "due_at": "2019-08-24T14:15:22Z",
  • "assigned_to_member_id": "f762546b-4e22-4cbc-845d-0a241ae61391"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Delete a housekeeping task

Authorizations:
apiKeyAuth
path Parameters
housekeepingTaskId
required
string <uuid>

Responses

Move a housekeeping task to a different workflow stage

Thin wrapper over the task workflow-stage endpoint (same approval/condition rules apply).

Authorizations:
apiKeyAuth
path Parameters
housekeepingTaskId
required
string <uuid>
Request Body schema: application/json
required
workflow_template_stage_id
required
string <uuid>
planned_start_at
string <date-time>
planned_end_at
string <date-time>
actual_start_at
string <date-time>
bypass_approvals
boolean

Requires the housekeeping_task.stage.bypass_approval permission.

Responses

Request samples

Content type
application/json
{
  • "workflow_template_stage_id": "79ea45b2-4be3-4980-a12d-3fd314348625",
  • "planned_start_at": "2019-08-24T14:15:22Z",
  • "planned_end_at": "2019-08-24T14:15:22Z",
  • "actual_start_at": "2019-08-24T14:15:22Z",
  • "bypass_approvals": true
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Edit planned dates, estimates, or progress on a specific workflow stage instance

Thin wrapper over the task workflow-stage-details endpoint. Unlike POST .../stage, this does not move the housekeeping task to a different stage -- it edits metadata on a stage instance already in workflow_stages or still planned in next_workflow_stages.

Authorizations:
apiKeyAuth
path Parameters
housekeepingTaskId
required
string <uuid>
taskWorkflowStageId
required
string <uuid>

The id of a specific TaskWorkflowStage instance (not a workflow_template_stage_id) -- either an already-entered stage (current or a past visit) or a still-planned one from next_workflow_stages.

Request Body schema: application/json
required
planned_start_at
string or null <date-time>
planned_end_at
string or null <date-time>
estimated_duration_value
number or null

Must be provided together with estimated_duration_unit.

estimated_duration_unit
string or null
Enum: "hours" "days"
progress
integer [ 0 .. 100 ]

Responses

Request samples

Content type
application/json
{
  • "planned_start_at": "2019-08-24T14:15:22Z",
  • "planned_end_at": "2019-08-24T14:15:22Z",
  • "estimated_duration_value": 0,
  • "estimated_duration_unit": "hours",
  • "progress": 100
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

SopTemplates

List SOP templates

An SOP is a Form (its fields are the checklist steps) plus linkage/purpose metadata -- see SopTemplate.

Authorizations:
apiKeyAuth
query Parameters
filter
string

key operator value filter convention. Supported keys: name, category, asset_category, booking_timing, form_id, is_active.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Create an SOP template

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
name
required
string
category
required
string (SopTemplateCategory)
Enum: "maintenance" "housekeeping" "inspection" "opening_closing"
asset_category
string or null
booking_timing
string or null (SopTemplateBookingTiming)
Enum: "pre_event" "post_event"

Set to run this SOP as a booking-triggered checklist at that point in a booking's lifecycle (see POST /bookings and the booking_status_changed Automation trigger). Null for SOPs not tied to bookings.

form_id
required
string <uuid>

Must refer to a form owned by this account.

is_active
boolean

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "category": "maintenance",
  • "asset_category": "string",
  • "booking_timing": "pre_event",
  • "form_id": "46af4ef5-2c18-4098-9bc5-c048fb90b843",
  • "is_active": true
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get an SOP template

Authorizations:
apiKeyAuth
path Parameters
sopTemplateId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update an SOP template

Authorizations:
apiKeyAuth
path Parameters
sopTemplateId
required
string <uuid>
Request Body schema: application/json
name
string
category
string (SopTemplateCategory)
Enum: "maintenance" "housekeeping" "inspection" "opening_closing"
asset_category
string or null
booking_timing
string or null (SopTemplateBookingTiming)
Enum: "pre_event" "post_event"

Set to run this SOP as a booking-triggered checklist at that point in a booking's lifecycle (see POST /bookings and the booking_status_changed Automation trigger). Null for SOPs not tied to bookings.

form_id
string <uuid>
is_active
boolean

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "category": "maintenance",
  • "asset_category": "string",
  • "booking_timing": "pre_event",
  • "form_id": "46af4ef5-2c18-4098-9bc5-c048fb90b843",
  • "is_active": true
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Deactivate an SOP template

Soft delete -- sets is_active to false, since SOP templates are referenced by maintenance request/recurring schedule history.

Authorizations:
apiKeyAuth
path Parameters
sopTemplateId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

TaskRecurrences

List task recurrences

Generic, domain-agnostic recurring-task scheduler -- not facilities-specific. Facilities PM/housekeeping schedules (see RecurringOperationalSchedule) are the first consumer of this, built as a thin wrapper on top, not a special case baked into this model.

Authorizations:
apiKeyAuth
query Parameters
filter
string

key operator value filter convention. Supported keys: name, frequency, is_active.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Create a task recurrence

A cron scans every 5 minutes for due recurrences (next_run_at in the past, is_active) and spawns one Task from task_template per firing, then advances next_run_at.

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
name
required
string
frequency
required
string
Enum: "daily" "weekly" "monthly"

custom_cron is rejected -- only daily/weekly/monthly are implemented (see TaskRecurrenceFrequency).

interval
integer >= 1
days_of_week
Array of integers or null[ items [ 0 .. 6 ] ]
day_of_month
integer or null [ 1 .. 31 ]
next_run_at
required
string <date-time>
ends_at
string or null <date-time>
required
object (TaskRecurrenceTemplate)

Template for the Task (plus optional domain-specific detail row) a TaskRecurrence spawns each time it fires. Mirrors POST /tasks's input shape, minus due_at (computed at spawn time from due_offset_days) and fields that don't make sense to template. TaskRecurrence itself has no domain knowledge -- detail_type/detail_payload are looked up in a handler registry that facilities (or any future feature) registers into; "maintenance_request_detail" and "housekeeping_task_detail" are the two registered today (see RecurringOperationalSchedule, which builds this template automatically from a simpler asset/location + timing input).

is_active
boolean
Default: true

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "frequency": "daily",
  • "interval": 1,
  • "days_of_week": [
    ],
  • "day_of_month": 1,
  • "next_run_at": "2019-08-24T14:15:22Z",
  • "ends_at": "2019-08-24T14:15:22Z",
  • "task_template": {
    },
  • "is_active": true
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get a task recurrence

Authorizations:
apiKeyAuth
path Parameters
taskRecurrenceId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update a task recurrence

Authorizations:
apiKeyAuth
path Parameters
taskRecurrenceId
required
string <uuid>
Request Body schema: application/json
name
string
frequency
string
Enum: "daily" "weekly" "monthly"
interval
integer >= 1
days_of_week
Array of integers or null[ items [ 0 .. 6 ] ]
day_of_month
integer or null [ 1 .. 31 ]
next_run_at
string <date-time>
ends_at
string or null <date-time>
object (TaskRecurrenceTemplate)

Template for the Task (plus optional domain-specific detail row) a TaskRecurrence spawns each time it fires. Mirrors POST /tasks's input shape, minus due_at (computed at spawn time from due_offset_days) and fields that don't make sense to template. TaskRecurrence itself has no domain knowledge -- detail_type/detail_payload are looked up in a handler registry that facilities (or any future feature) registers into; "maintenance_request_detail" and "housekeeping_task_detail" are the two registered today (see RecurringOperationalSchedule, which builds this template automatically from a simpler asset/location + timing input).

is_active
boolean

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "frequency": "daily",
  • "interval": 1,
  • "days_of_week": [
    ],
  • "day_of_month": 1,
  • "next_run_at": "2019-08-24T14:15:22Z",
  • "ends_at": "2019-08-24T14:15:22Z",
  • "task_template": {
    },
  • "is_active": true
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Delete a task recurrence

Stops future firings. Tasks it already spawned are unaffected.

Authorizations:
apiKeyAuth
path Parameters
taskRecurrenceId
required
string <uuid>

Responses

RecurringOperationalSchedules

List recurring operational schedules

Facilities-specific preventive-maintenance/housekeeping schedules -- thin wrappers around a TaskRecurrence (see RecurringOperationalSchedule), giving proper FK columns for facilities queries like "PM schedules for asset X" instead of reaching into TaskRecurrence's generic JSONB template.

Authorizations:
apiKeyAuth
query Parameters
filter
string

key operator value filter convention. Supported keys: schedule_type, target_type, target_id, sop_template_id.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Create a recurring operational schedule

Creates a TaskRecurrence (with a task_template built from schedule_type/target/sop_template_id) and this wrapper row around it, in one transaction. schedule_type "preventive_maintenance" spawns maintenance-request tasks with request_type "preventive"; "housekeeping" spawns housekeeping tasks, using the linked SOP's form as checklist_form_id if sop_template_id is set.

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
name
required
string

Used as both the underlying TaskRecurrence's name and the title of each task it spawns.

schedule_type
required
string (RecurringOperationalScheduleType)
Enum: "preventive_maintenance" "housekeeping"
target_type
required
string (RecurringOperationalTargetType)
Enum: "asset" "location"
target_id
required
string <uuid>

Must refer to an asset or location (per target_type) owned by this account.

sop_template_id
string or null <uuid>

For schedule_type housekeeping, used as the spawned task's checklist_form_id (via the SOP's form_id). Must refer to an SOP template owned by this account.

frequency
required
string
Enum: "daily" "weekly" "monthly"
interval
integer >= 1
days_of_week
Array of integers or null[ items [ 0 .. 6 ] ]
day_of_month
integer or null [ 1 .. 31 ]
next_run_at
required
string <date-time>
ends_at
string or null <date-time>
assigned_to_member_id
string <uuid>
priority
string (TaskPriority)
Enum: "high" "medium" "low"

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "schedule_type": "preventive_maintenance",
  • "target_type": "asset",
  • "target_id": "d3bcdc92-4191-401b-ad0c-42056c6efab9",
  • "sop_template_id": "509744fe-18db-4787-b961-91e337a8f6aa",
  • "frequency": "daily",
  • "interval": 1,
  • "days_of_week": [
    ],
  • "day_of_month": 1,
  • "next_run_at": "2019-08-24T14:15:22Z",
  • "ends_at": "2019-08-24T14:15:22Z",
  • "assigned_to_member_id": "f762546b-4e22-4cbc-845d-0a241ae61391",
  • "priority": "high"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get a recurring operational schedule

Authorizations:
apiKeyAuth
path Parameters
scheduleId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update a recurring operational schedule's scheduling fields

Only scheduling fields (frequency, interval, next_run_at, ends_at, is_active, ...) can be changed -- target/sop_template are fixed at creation (create a new schedule to change what's targeted). Delegates to the underlying TaskRecurrence.

Authorizations:
apiKeyAuth
path Parameters
scheduleId
required
string <uuid>
Request Body schema: application/json
is_active
boolean
frequency
string
Enum: "daily" "weekly" "monthly"
interval
integer >= 1
days_of_week
Array of integers or null[ items [ 0 .. 6 ] ]
day_of_month
integer or null [ 1 .. 31 ]
next_run_at
string <date-time>
ends_at
string or null <date-time>

Responses

Request samples

Content type
application/json
{
  • "is_active": true,
  • "frequency": "daily",
  • "interval": 1,
  • "days_of_week": [
    ],
  • "day_of_month": 1,
  • "next_run_at": "2019-08-24T14:15:22Z",
  • "ends_at": "2019-08-24T14:15:22Z"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Delete a recurring operational schedule

Deletes via the owning TaskRecurrence -- its ON DELETE CASCADE takes this wrapper row with it.

Authorizations:
apiKeyAuth
path Parameters
scheduleId
required
string <uuid>

Responses

Facilities

Get aggregate dashboard data for facilities operations

Returns account-wide stats for the facilities overview dashboard: maintenance requests by workflow stage, open requests by severity, open/overdue counts, upcoming and overdue preventive-maintenance schedule counts, housekeeping tasks by stage and completion rate over the last 30 days, and an equipment-downtime proxy per asset over the last 30 days. Returns zeroed/empty fields if the account has no maintenance request yet.

Authorizations:
apiKeyAuth
query Parameters
location_id
string <uuid>

Scopes maintenance-request and housekeeping stats to this location. Note this only matches area-level maintenance requests (location_id set directly) -- asset-scoped breakdown requests aren't filtered by their asset's location. Also scopes the preventive-maintenance counts to preventive_maintenance schedules whose target_type is "location" and target_id matches.

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

BookingResources

List booking resources

Lists the account's bookable resources (restaurant tables or event halls).

Authorizations:
apiKeyAuth
query Parameters
filter
string

key operator value filter convention (see GET /customers for the general syntax). Supported keys: name, type, layout_id, location_id.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Create a booking resource

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
name
required
string
type
required
string
Enum: "restaurant_table" "event_hall"
capacity
integer or null
notes
string or null
layout_id
string or null <uuid>

Must refer to a booking_resource_layout owned by this account.

location_id
string or null <uuid>

Must refer to a location owned by this account.

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "type": "restaurant_table",
  • "capacity": 0,
  • "notes": "string",
  • "layout_id": "118c4a32-91d1-4a21-89a4-a345ccd91280",
  • "location_id": "46910cc3-ab41-4b80-b4a7-94dab9f1b795"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Create multiple booking resources at once

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
required
Array of objects (BookingResourceInput) non-empty

Responses

Request samples

Content type
application/json
{
  • "resources": [
    ]
}

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Get a booking resource

Authorizations:
apiKeyAuth
path Parameters
resourceId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update a booking resource

Authorizations:
apiKeyAuth
path Parameters
resourceId
required
string <uuid>
Request Body schema: application/json
name
string
type
string
Enum: "restaurant_table" "event_hall"
capacity
integer or null
notes
string or null
layout_id
string or null <uuid>

Must refer to a booking_resource_layout owned by this account. Pass null to unassign.

location_id
string or null <uuid>

Must refer to a location owned by this account. Pass null to unassign.

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "type": "restaurant_table",
  • "capacity": 0,
  • "notes": "string",
  • "layout_id": "118c4a32-91d1-4a21-89a4-a345ccd91280",
  • "location_id": "46910cc3-ab41-4b80-b4a7-94dab9f1b795"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Delete a booking resource

Authorizations:
apiKeyAuth
path Parameters
resourceId
required
string <uuid>

Responses

Bookings

List bookings

Lists bookings (restaurant reservations or event hall bookings) for the account.

Authorizations:
apiKeyAuth
query Parameters
filter
string

key operator value filter convention (see GET /customers for the general syntax). Supported keys: resource_id, location_id, customer_id, status, start_time, end_time, created_at, id. resource_id matches bookings that have the given resource among their resources (a booking can have more than one).

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Create a booking

Creates a booking, optionally reserving one or more booking resources (e.g. two tables for a large party). If resource_ids is set, rejects the request with 409 if any of the resources already has a non-cancelled/no_show booking overlapping the requested [start_time, end_time) range. Each resource_id must refer to a booking_resource owned by this account; customer_id must refer to a customer owned by this account (provider_account_id); location_id must refer to a root location (parent_id is null) owned by this account.

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
resource_ids
Array of strings <uuid> [ items <uuid > ]

Booking resources to reserve for this booking. Each must be owned by this account.

location_id
string <uuid>

Must refer to a root location (parent_id is null) owned by this account.

customer_id
string <uuid>
start_time
required
string <date-time>
end_time
required
string <date-time>
party_size
required
integer
status
string (BookingStatus)
Enum: "pending" "confirmed" "seated" "completed" "cancelled" "no_show"
object (Money)
object (Money)
deposit_paid_at
string <date-time>
notes
string or null

Responses

Request samples

Content type
application/json
{
  • "resource_ids": [
    ],
  • "location_id": "46910cc3-ab41-4b80-b4a7-94dab9f1b795",
  • "customer_id": "160c0c4b-9966-4dc1-a916-8407eb10d74e",
  • "start_time": "2019-08-24T14:15:22Z",
  • "end_time": "2019-08-24T14:15:22Z",
  • "party_size": 0,
  • "status": "pending",
  • "amount": {
    },
  • "deposit_amount": {
    },
  • "deposit_paid_at": "2019-08-24T14:15:22Z",
  • "notes": "string"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get a booking

Authorizations:
apiKeyAuth
path Parameters
bookingId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update a booking

If resource_ids is passed, it fully replaces the booking's current set of resources (pass an empty array to clear all resources). If resource_ids, start_time, or end_time changes (and the booking has one or more resources), re-runs the overlap check against those resources' other non-cancelled/no_show bookings.

Authorizations:
apiKeyAuth
path Parameters
bookingId
required
string <uuid>
Request Body schema: application/json
resource_ids
Array of strings <uuid> [ items <uuid > ]

Replaces the booking's full set of resources. Omit to leave resources unchanged.

location_id
string or null <uuid>

Must refer to a root location (parent_id is null) owned by this account. Pass null to unlink.

customer_id
string or null <uuid>
start_time
string <date-time>
end_time
string <date-time>
party_size
integer
status
string (BookingStatus)
Enum: "pending" "confirmed" "seated" "completed" "cancelled" "no_show"
object (Money)
object (Money)
deposit_paid_at
string or null <date-time>
cancellation_reason
string or null
notes
string or null

Responses

Request samples

Content type
application/json
{
  • "resource_ids": [
    ],
  • "location_id": "46910cc3-ab41-4b80-b4a7-94dab9f1b795",
  • "customer_id": "160c0c4b-9966-4dc1-a916-8407eb10d74e",
  • "start_time": "2019-08-24T14:15:22Z",
  • "end_time": "2019-08-24T14:15:22Z",
  • "party_size": 0,
  • "status": "pending",
  • "amount": {
    },
  • "deposit_amount": {
    },
  • "deposit_paid_at": "2019-08-24T14:15:22Z",
  • "cancellation_reason": "string",
  • "notes": "string"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Delete a booking

Authorizations:
apiKeyAuth
path Parameters
bookingId
required
string <uuid>

Responses

BookingResourceLayouts

List booking resource layouts

Lists the account's booking resource layouts (floor plans / seating charts), including each layout's items (and each item's linked booking resource, if any).

Authorizations:
apiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Create a booking resource layout

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
name
required
string
description
string or null
background_image_url
string or null
canvas_width
integer

Defaults to 1000.

canvas_height
integer

Defaults to 800.

location_id
string or null <uuid>

Must refer to a location owned by this account.

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "description": "string",
  • "background_image_url": "string",
  • "canvas_width": 0,
  • "canvas_height": 0,
  • "location_id": "46910cc3-ab41-4b80-b4a7-94dab9f1b795"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get a booking resource layout

Returns the layout together with its items (and each item's linked booking resource, if any).

Authorizations:
apiKeyAuth
path Parameters
layoutId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update a booking resource layout

Authorizations:
apiKeyAuth
path Parameters
layoutId
required
string <uuid>
Request Body schema: application/json
name
string
description
string or null
background_image_url
string or null
canvas_width
integer
canvas_height
integer
location_id
string or null <uuid>

Must refer to a location owned by this account. Pass null to unlink.

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "description": "string",
  • "background_image_url": "string",
  • "canvas_width": 0,
  • "canvas_height": 0,
  • "location_id": "46910cc3-ab41-4b80-b4a7-94dab9f1b795"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Delete a booking resource layout

Deleting a layout cascades to its items. Booking resources that were linked to this layout (via their layout_id) have that link cleared, but are not deleted.

Authorizations:
apiKeyAuth
path Parameters
layoutId
required
string <uuid>

Responses

Add an item to a layout

Adds a single draggable item (table, chair, wall, decoration, ...) to the layout's canvas.

Authorizations:
apiKeyAuth
path Parameters
layoutId
required
string <uuid>
Request Body schema: application/json
required
resource_id
string or null <uuid>

Must refer to a booking_resource owned by this account.

item_type
required
string (BookingResourceLayoutItemType)
Enum: "table" "chair" "bar" "stage" "wall" "door" "plant" "text" "custom"
label
string or null
shape
string (BookingResourceLayoutItemShape)
Enum: "rectangle" "circle"
required
object (BookingResourceLayoutItemPosition)
z_index
integer

Responses

Request samples

Content type
application/json
{
  • "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
  • "item_type": "table",
  • "label": "string",
  • "shape": "rectangle",
  • "position": {
    },
  • "z_index": 0
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Add multiple items to a layout at once

Authorizations:
apiKeyAuth
path Parameters
layoutId
required
string <uuid>
Request Body schema: application/json
required
required
Array of objects (BookingResourceLayoutItemInput) non-empty

Responses

Request samples

Content type
application/json
{
  • "items": [
    ]
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Save dragged item positions in bulk

Intended for drag-and-drop editors: pass the new position (and optionally z_index) for any number of existing items in one call to persist the whole canvas arrangement at once.

Authorizations:
apiKeyAuth
path Parameters
layoutId
required
string <uuid>
Request Body schema: application/json
required
required
Array of objects (BookingResourceLayoutItemPositionUpdate) non-empty

Responses

Request samples

Content type
application/json
{
  • "items": [
    ]
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update a single layout item

Authorizations:
apiKeyAuth
path Parameters
layoutId
required
string <uuid>
itemId
required
string <uuid>
Request Body schema: application/json
resource_id
string or null <uuid>
item_type
string (BookingResourceLayoutItemType)
Enum: "table" "chair" "bar" "stage" "wall" "door" "plant" "text" "custom"
label
string or null
shape
string (BookingResourceLayoutItemShape)
Enum: "rectangle" "circle"
object (BookingResourceLayoutItemPosition)
z_index
integer

Responses

Request samples

Content type
application/json
{
  • "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
  • "item_type": "table",
  • "label": "string",
  • "shape": "rectangle",
  • "position": {
    },
  • "z_index": 0
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Remove an item from a layout

Authorizations:
apiKeyAuth
path Parameters
layoutId
required
string <uuid>
itemId
required
string <uuid>

Responses

Deals

List deals

Lists tasks joined with their deal_detail, customer, and contact. If pipeline_id is given, scopes to that one deal_pipeline entity; otherwise scopes to the union of all of the account's deal_pipeline entities. Returns an empty list if no pipeline has been created yet (the default pipeline is provisioned lazily on first deal creation).

Authorizations:
apiKeyAuth
query Parameters
pipeline_id
string <uuid>

Restrict the list to deals in this deal_pipeline entity. Omit to list deals across all of the account's pipelines.

filter
string

key operator value filter convention (see GET /customers for the general syntax). Supported keys: title, priority, due_at, assigned_to_member_id, participant_member_id, created_at, id (Task fields), and customer_id, contact_id, deal_number, status, expected_close_at, actual_close_at, source, lost_reason, created_by_member_id (deal_detail fields).

limit
integer <= 100
Default: 20
offset
integer
Default: 0

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Create a deal

Creates a Task in a deal_pipeline entity (plus its deal_detail row). Targets pipeline_id if given (must be a pipeline owned by this account); otherwise targets the account's default pipeline, lazily provisioning one named "Sales Pipeline" on first use. No Project is involved; deal permissions are account-scoped. Fails with 400 if the account's deal_limit plan limit has been reached. deal_number, if omitted, is auto-generated from the account's current deal numbering settings (see /deals/settings/numbering) and is snapshotted at creation time -- later prefix/counter changes never retroactively affect already-created deals.

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
title
required
string
description
string
customer_id
string <uuid>
contact_id
string <uuid>
deal_number
string or null

Auto-generated from account settings if omitted; pass a value to override.

object (Money)
probability
integer [ 0 .. 100 ]
expected_close_at
string <date>
source
string
priority
string (TaskPriority)
Enum: "high" "medium" "low"
due_at
string <date-time>
assigned_to_member_id
string <uuid>
pipeline_id
string <uuid>

Target deal_pipeline entity. Defaults to the account's first (oldest) pipeline, auto-provisioning one named "Sales Pipeline" if none exists yet.

Responses

Request samples

Content type
application/json
{
  • "title": "string",
  • "description": "string",
  • "customer_id": "160c0c4b-9966-4dc1-a916-8407eb10d74e",
  • "contact_id": "f245e2a3-e141-4d41-912c-b1c1f5bd5598",
  • "deal_number": "string",
  • "amount": {
    },
  • "probability": 100,
  • "expected_close_at": "2019-08-24",
  • "source": "string",
  • "priority": "high",
  • "due_at": "2019-08-24T14:15:22Z",
  • "assigned_to_member_id": "f762546b-4e22-4cbc-845d-0a241ae61391",
  • "pipeline_id": "ec036e81-7903-4e4d-bbfa-ac8516341cf0"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get the account's deal numbering settings

Authorizations:
apiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update the account's deal numbering prefix and/or reset the counter

A manual settings action -- purely a config write, never alters deal_number on already-created deals.

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
prefix
string non-empty
reset_counter_to
integer >= 0

Responses

Request samples

Content type
application/json
{
  • "prefix": "string",
  • "reset_counter_to": 0
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get a deal

Authorizations:
apiKeyAuth
path Parameters
dealId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update a deal

Authorizations:
apiKeyAuth
path Parameters
dealId
required
string <uuid>
Request Body schema: application/json
title
string
description
string
customer_id
string or null <uuid>
contact_id
string or null <uuid>
deal_number
string or null
object (Money)
probability
integer [ 0 .. 100 ]
expected_close_at
string or null <date>
lost_reason
string or null
source
string or null
priority
string (TaskPriority)
Enum: "high" "medium" "low"
due_at
string <date-time>
assigned_to_member_id
string <uuid>

Responses

Request samples

Content type
application/json
{
  • "title": "string",
  • "description": "string",
  • "customer_id": "160c0c4b-9966-4dc1-a916-8407eb10d74e",
  • "contact_id": "f245e2a3-e141-4d41-912c-b1c1f5bd5598",
  • "deal_number": "string",
  • "amount": {
    },
  • "probability": 100,
  • "expected_close_at": "2019-08-24",
  • "lost_reason": "string",
  • "source": "string",
  • "priority": "high",
  • "due_at": "2019-08-24T14:15:22Z",
  • "assigned_to_member_id": "f762546b-4e22-4cbc-845d-0a241ae61391"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Delete a deal

Authorizations:
apiKeyAuth
path Parameters
dealId
required
string <uuid>

Responses

Move a deal to a different pipeline stage

Thin wrapper over the task workflow-stage endpoint (same approval/condition rules apply, see /tasks/{taskId}/workflow_stages). If the target stage's stage_type is done, deal_detail.status becomes won; if cancelled, it becomes lost — both set actual_close_at to today.

Authorizations:
apiKeyAuth
path Parameters
dealId
required
string <uuid>
Request Body schema: application/json
required
workflow_template_stage_id
required
string <uuid>
planned_start_at
string <date-time>
planned_end_at
string <date-time>
actual_start_at
string <date-time>
bypass_approvals
boolean

Requires the deal.stage.bypass_approval permission.

Responses

Request samples

Content type
application/json
{
  • "workflow_template_stage_id": "79ea45b2-4be3-4980-a12d-3fd314348625",
  • "planned_start_at": "2019-08-24T14:15:22Z",
  • "planned_end_at": "2019-08-24T14:15:22Z",
  • "actual_start_at": "2019-08-24T14:15:22Z",
  • "bypass_approvals": true
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

List interactions logged against a deal

Authorizations:
apiKeyAuth
path Parameters
dealId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Log an interaction against a deal

The interaction is attributed to the deal's linked customer (deal_detail.customer_id); fails 400 if the deal has no linked customer.

Authorizations:
apiKeyAuth
path Parameters
dealId
required
string <uuid>
Request Body schema: application/json
required
contact_id
string <uuid>
type
required
string (CustomerInteractionType)
Enum: "call" "email" "meeting" "note" "whatsapp" "instagram"
subject
string or null
content
string or null
occurred_at
string <date-time>

Responses

Request samples

Content type
application/json
{
  • "contact_id": "f245e2a3-e141-4d41-912c-b1c1f5bd5598",
  • "type": "call",
  • "subject": "string",
  • "content": "string",
  • "occurred_at": "2019-08-24T14:15:22Z"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

DealPipelines

List deal pipelines

Lists the account's deal_pipeline entities, oldest first, each including its workflow_template and stages.

Authorizations:
apiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Create a deal pipeline

Creates a new deal_pipeline entity with its own workflow. Fails with 400 if the account's pipeline_limit plan limit has been reached.

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
name
required
string
description
string or null
object

Defaults to the standard "Prospecting → Qualified → Proposal → Negotiation → Closed Won/Lost" stages if omitted.

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "description": "string",
  • "workflow_template": {
    }
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get a deal pipeline

Authorizations:
apiKeyAuth
path Parameters
pipelineId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Rename or update the description of a deal pipeline

Authorizations:
apiKeyAuth
path Parameters
pipelineId
required
string <uuid>
Request Body schema: application/json
name
string
description
string or null

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "description": "string"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Delete a deal pipeline

Fails with 400 if the pipeline still has deals in it — move or delete them first.

Authorizations:
apiKeyAuth
path Parameters
pipelineId
required
string <uuid>

Responses

Invoices

List invoices

Invoices are a standalone resource (not backed by Task/Entity, unlike Deals). Each entry includes computed balance_due, is_overdue, and display_number fields alongside stored data, plus any custom_fields values (resource_type "invoice").

Authorizations:
apiKeyAuth
query Parameters
filter
string

key operator value filter convention (see GET /customers for the general syntax). Supported keys: customer_id, deal_task_id, status.

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Create an invoice

Creates a draft invoice for a customer. line_items must be non-empty and all share the same currency; amount is server-computed from line_items (never accepted as direct input), including any exclusive taxes in each line item's tax_config (added on top of quantity * unit_amount_cents); inclusive taxes are assumed to already be part of unit_amount_cents and do not add further. Line items and/or the invoice itself may carry a discount (percentage or flat, with an authoritative amount_cents); line-item discounts are subtracted before exclusive tax, and the invoice-level discount is subtracted from the running total last. The invoice number and number_prefix are assigned by a DB trigger from the account's current invoice numbering settings (see /invoices/settings/numbering) and are snapshotted at creation time — later prefix/counter changes never retroactively affect already-created invoices. If due_date is omitted and the customer has preferences.billing_details.payment_terms_days set, due_date is auto-computed from issue_date (or today) plus that many days. custom_fields, if provided, are upserted against custom field definitions (must already exist, created via /custom-fields) in the same transaction as the invoice itself.

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
customer_id
required
string <uuid>
contact_id
string <uuid>
deal_task_id
string <uuid>
required
Array of objects (InvoiceLineItem) non-empty
object or null
issue_date
string <date>
due_date
string <date>
notes
string or null
Array of objects (CustomFieldValueInput)

Values to set for custom fields defined with resource_type "invoice" (or no resource_types restriction). Upserted after the invoice is created.

Responses

Request samples

Content type
application/json
{
  • "customer_id": "160c0c4b-9966-4dc1-a916-8407eb10d74e",
  • "contact_id": "f245e2a3-e141-4d41-912c-b1c1f5bd5598",
  • "deal_task_id": "108d0e2d-f38c-482d-9609-5d73bdaccb57",
  • "line_items": [
    ],
  • "discount": {
    },
  • "issue_date": "2019-08-24",
  • "due_date": "2019-08-24",
  • "notes": "string",
  • "custom_fields": [
    ]
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get the account's invoice numbering settings

Authorizations:
apiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update the account's invoice numbering prefix and/or reset the counter

A manual settings action (e.g. run once at the start of a new fiscal year to switch the prefix and restart numbering from 1). Purely a config write — never alters number_prefix/number on already-created invoices. If a reset produces a (prefix, number) combination that collides with an existing invoice, the next invoice created under that combination fails with a database uniqueness error.

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
prefix
string non-empty
reset_counter_to
integer >= 0

Responses

Request samples

Content type
application/json
{
  • "prefix": "string",
  • "reset_counter_to": 0
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get an invoice

Authorizations:
apiKeyAuth
path Parameters
invoiceId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update a draft invoice

Only allowed while status is draft. Once an invoice has been sent, line_items/amount/discount/customer_id/ contact_id/deal_task_id/issue_date are locked — correct mistakes by voiding and creating a new invoice instead. due_date remains editable at any stage via this endpoint regardless of status (not locked). status itself is never settable here; it only changes via /send, /void, /payments, and /credit-notes. custom_fields values are upserted regardless of the invoice's draft-only restriction on the other fields.

Authorizations:
apiKeyAuth
path Parameters
invoiceId
required
string <uuid>
Request Body schema: application/json
required
customer_id
string <uuid>
contact_id
string or null <uuid>
deal_task_id
string or null <uuid>
Array of objects (InvoiceLineItem) non-empty
object or null
issue_date
string or null <date>
due_date
string or null <date>
notes
string or null
Array of objects (CustomFieldValueInput)

Values to upsert for custom fields defined with resource_type "invoice" (or no resource_types restriction).

Responses

Request samples

Content type
application/json
{
  • "customer_id": "160c0c4b-9966-4dc1-a916-8407eb10d74e",
  • "contact_id": "f245e2a3-e141-4d41-912c-b1c1f5bd5598",
  • "deal_task_id": "108d0e2d-f38c-482d-9609-5d73bdaccb57",
  • "line_items": [
    ],
  • "discount": {
    },
  • "issue_date": "2019-08-24",
  • "due_date": "2019-08-24",
  • "notes": "string",
  • "custom_fields": [
    ]
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Delete a draft invoice

Only allowed while status is draft. Non-draft invoices must be voided instead of deleted.

Authorizations:
apiKeyAuth
path Parameters
invoiceId
required
string <uuid>

Responses

Mark a draft invoice as sent

draft -> sent only. Sets issue_date to today if not already set. Locks line_items/amount/customer_id/contact_id/deal_task_id for further edits.

Authorizations:
apiKeyAuth
path Parameters
invoiceId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Void an invoice

Allowed from draft, sent, or partially_paid. Cannot void a paid or already-void invoice.

Authorizations:
apiKeyAuth
path Parameters
invoiceId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Record a payment against an invoice

Only allowed once the invoice is sent or partially_paid (not draft, void, or already fully paid). Payment currency must match the invoice's currency. Rejects amount_cents greater than the remaining balance (amount minus sum of prior payments and issued credit notes). Status is recomputed automatically from payments plus issued credit notes combined: partially_paid once the combined total is short of the full amount, paid once it covers the full amount (a fully-offsetting credit note alone can settle an invoice with no payment).

Authorizations:
apiKeyAuth
path Parameters
invoiceId
required
string <uuid>
Request Body schema: application/json
required
amount_cents
required
integer >= 1
currency
required
string
paid_at
string <date>
method
string or null
note
string or null

Responses

Request samples

Content type
application/json
{
  • "amount_cents": 1,
  • "currency": "string",
  • "paid_at": "2019-08-24",
  • "method": "string",
  • "note": "string"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Remove a payment from an invoice

Corrects a mistaken payment entry. Invoice status is recomputed downward afterward (e.g. paid -> partially_paid or partially_paid -> sent).

Authorizations:
apiKeyAuth
path Parameters
invoiceId
required
string <uuid>
paymentId
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Download an invoice as a PDF

Generated on demand for each request (not cached or stored). Streams application/pdf with a Content-Disposition attachment header using the invoice's display_number as the filename. Any custom field values on the invoice whose custom field definition has show_on_pdf set to true are rendered on the PDF (as "Field name: value"); fields without show_on_pdf are stored but omitted from the PDF. Reflects the account's invoice branding settings (see /invoices/settings/branding): logo/letterhead images, accent color, custom company_name, and footer_text, if configured.

Authorizations:
apiKeyAuth
path Parameters
invoiceId
required
string <uuid>

Responses

Reminders

List follow-up reminders

Generic follow-up reminders that can be attached to a task, deal, customer, or invoice. Deals are Task rows under the hood (keyed by DealDetail.task_id), so a deal's reminders use resource_type "deal" with that same task_id as resource_id. Shared reminders are visible to any member; private reminders are only returned to their creator or assignee.

Authorizations:
apiKeyAuth
query Parameters
filter
string

key operator value filter convention (see GET /customers for the general syntax). Supported keys: resource_type, resource_id, status, assigned_to_member_id, created_by_member_id, title, id.

sort_by
string
Enum: "due_at" "status" "resource_type" "resource_id" "assigned_to_member_id" "created_by_member_id" "created_at" "updated_at"
sort_order
string
Enum: "asc" "desc"

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Create a follow-up reminder

Validates that resource_id refers to an existing task, deal, customer, or invoice on the account (for resource_type "deal", resource_id must be a task that has a DealDetail). Defaults assigned_to_member_id to the creator and visibility to "shared".

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
resource_type
required
string (ReminderResourceType)
Enum: "task" "deal" "customer" "invoice"
resource_id
required
string <uuid>
title
required
string
note
string or null
due_at
required
string <date-time>
assigned_to_member_id
string or null <uuid>

Defaults to the creator if omitted. Ignored (always forced to the creator) when visibility is "private".

visibility
string (ReminderVisibility)
Enum: "shared" "private"

Responses

Request samples

Content type
application/json
{
  • "resource_type": "task",
  • "resource_id": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
  • "title": "string",
  • "note": "string",
  • "due_at": "2019-08-24T14:15:22Z",
  • "assigned_to_member_id": "f762546b-4e22-4cbc-845d-0a241ae61391",
  • "visibility": "shared"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Update, reschedule, reassign, complete, or dismiss a reminder

Setting due_at reschedules the reminder and clears its notified state so it will fire again. Setting status to "completed" or "dismissed" stops it from firing. Setting assigned_to_member_id to a different member sends them a reminder_assigned notification. If the reminder's visibility is (or is being set to) "private", assigned_to_member_id is ignored and forced back to the creator. A reminder that is already "completed" or "dismissed" is locked — any request that doesn't reopen it by setting status to "pending" is rejected with 409.

Authorizations:
apiKeyAuth
path Parameters
id
required
string <uuid>
Request Body schema: application/json
title
string
note
string or null
due_at
string <date-time>
assigned_to_member_id
string or null <uuid>
visibility
string (ReminderVisibility)
Enum: "shared" "private"
status
string (ReminderStatus)
Enum: "pending" "completed" "dismissed"

Responses

Request samples

Content type
application/json
{
  • "title": "string",
  • "note": "string",
  • "due_at": "2019-08-24T14:15:22Z",
  • "assigned_to_member_id": "f762546b-4e22-4cbc-845d-0a241ae61391",
  • "visibility": "shared",
  • "status": "pending"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Delete a reminder

Authorizations:
apiKeyAuth
path Parameters
id
required
string <uuid>

Responses

Insights

Extract product insights from a website URL

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
url
required
string

Responses

Request samples

Content type
application/json
{
  • "url": "string"
}

Get suggested entities for a project

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
object

Responses

Request samples

Content type
application/json
{ }

Get suggested stages for a workflow

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
object

Responses

Request samples

Content type
application/json
{ }

Extract tasks from text

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
text
required
string

Responses

Request samples

Content type
application/json
{
  • "text": "string"
}

Classify the type of a document

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
content
required
string

Responses

Request samples

Content type
application/json
{
  • "content": "string"
}

Extract tasks from a document

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
document_id
required
string <uuid>

Responses

Request samples

Content type
application/json
{
  • "document_id": "b792e8ae-2cb4-4209-85b9-32be4c2fcdd6"
}

Extract feedback items from a document

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
document_id
required
string <uuid>

Responses

Request samples

Content type
application/json
{
  • "document_id": "b792e8ae-2cb4-4209-85b9-32be4c2fcdd6"
}

Draft a follow-up message from feedback items

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
object

Responses

Request samples

Content type
application/json
{ }

Generate product creation data from a website

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
url
required
string

Responses

Request samples

Content type
application/json
{
  • "url": "string"
}

Slack

Handle a Slack slash command for tasklets

Authorizations:
apiKeyAuth

Responses

Handle Slack interactive component payloads

Authorizations:
apiKeyAuth

Responses

Handle Slack event API payloads

Authorizations:
apiKeyAuth

Responses

Whatsapp

Get the account's WhatsApp connection status

Authorizations:
apiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Link a WhatsApp Business Account via Embedded Signup

Exchanges the code returned by Meta's client-side Embedded Signup flow for a long-lived access token, subscribes the app to the WABA's webhooks, and stores the connection on the account.

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
code
required
string

The authorization code returned by Meta's WhatsApp Embedded Signup flow in the browser.

waba_id
required
string

The WhatsApp Business Account id selected during Embedded Signup.

phone_number_id
required
string

The phone number id selected during Embedded Signup.

Responses

Request samples

Content type
application/json
{
  • "code": "string",
  • "waba_id": "string",
  • "phone_number_id": "string"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Unlink the account's WhatsApp Business Account

Authorizations:
apiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Send a WhatsApp message to a customer or contact

Sends a free-form text message or an approved template message. Free-form text only delivers within the 24-hour customer service window opened by the customer's last inbound message; outside that window (including the first message to a customer), use type "template" with a name from GET /whatsapp/templates. The destination number is resolved from to, else the given contact's phone contact method, else rejected. Always logs a CustomerInteraction (type "whatsapp") and a WhatsappMessage row, even if the send to Meta fails (status is set to "failed" with the error recorded).

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
customer_id
required
string <uuid>
contact_id
string <uuid>

Defaults to resolving the customer's contact phone number when omitted.

to
string

Explicit destination phone number; overrides contact/customer lookup.

type
string
Default: "text"
Enum: "text" "template"
body
string

Required when type is "text". Optional caption/summary when type is "template".

template_name
string

Required when type is "template". Must be an approved template name from GET /whatsapp/templates.

template_language
string

Required when type is "template", e.g. "en_US".

template_components
Array of objects

WhatsApp template component parameters (header/body/button variables), passed through to the Graph API as-is.

Responses

Request samples

Content type
application/json
{
  • "customer_id": "160c0c4b-9966-4dc1-a916-8407eb10d74e",
  • "contact_id": "f245e2a3-e141-4d41-912c-b1c1f5bd5598",
  • "to": "string",
  • "type": "text",
  • "body": "string",
  • "template_name": "string",
  • "template_language": "string",
  • "template_components": [
    ]
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get the WhatsApp message timeline for a customer

Authorizations:
apiKeyAuth
query Parameters
customer_id
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

List the account's approved WhatsApp message templates

Fetched live from Meta (not cached locally). Required for sending a message outside the 24-hour customer service window.

Authorizations:
apiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Create a new WhatsApp message template

Submits a template to Meta for review via the WhatsApp Business Account. Newly created templates start in "PENDING" status and are not usable for sending until Meta approves them; check GET /whatsapp/templates for the current status.

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
name
required
string^[a-z0-9_]+$

Lowercase letters, numbers, and underscores only, per Meta's template naming rules.

category
required
string
Enum: "MARKETING" "UTILITY" "AUTHENTICATION"
language
required
string

WhatsApp locale code, e.g. "en_US".

components
required
Array of objects non-empty

Template component definitions (HEADER/BODY/FOOTER/BUTTONS), passed through to the Graph API as-is.

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "category": "MARKETING",
  • "language": "string",
  • "components": [
    ]
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Meta webhook verification handshake

Called by Meta when configuring the webhook subscription. Authenticated via the hub.verify_token query param matching WHATSAPP_WEBHOOK_VERIFY_TOKEN, not member session.

Authorizations:
apiKeyAuth
query Parameters
hub.mode
string
hub.verify_token
string
hub.challenge
string

Responses

Receive inbound WhatsApp messages and delivery status callbacks

Authenticated via the X-Hub-Signature-256 header (HMAC of the body with WHATSAPP_APP_SECRET), not member session. Inbound messages are matched to a Contact by phone number and logged as a CustomerInteraction. If no Contact matches, a new Customer (type "unknown") and Contact are auto-created using the sender's WhatsApp profile name (falling back to their phone number) so the conversation is never dropped. Responds 200 immediately and processes the payload after acknowledging, per Meta's requirements.

Authorizations:
apiKeyAuth

Responses

Instagram

Get the account's Instagram connection status

Authorizations:
apiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Link an Instagram professional account via Facebook Login

Exchanges the code returned by Meta's client-side Facebook Login flow for a user access token, resolves the Instagram professional account connected to the given Facebook Page, subscribes the app to the page's messaging webhooks, and stores the connection on the account.

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
code
required
string

The authorization code returned by Meta's Facebook Login flow in the browser.

page_id
required
string

The Facebook Page id selected during login; must have a connected Instagram professional account.

Responses

Request samples

Content type
application/json
{
  • "code": "string",
  • "page_id": "string"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Unlink the account's Instagram account

Authorizations:
apiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}

Send an Instagram DM to a customer or contact

Sends a free-form text DM. Instagram's messaging platform only allows replying within the standard messaging window opened by the contact's last inbound DM — there is no template mechanism to message someone cold, unlike WhatsApp. The recipient is resolved from to, else the igsid captured from the given contact's most recent inbound message, else rejected. Always logs a CustomerInteraction (type "instagram") and an InstagramMessage row, even if the send to Meta fails (status is set to "failed" with the error recorded).

Authorizations:
apiKeyAuth
Request Body schema: application/json
required
customer_id
required
string <uuid>
contact_id
string <uuid>

Defaults to resolving the igsid captured from the contact's most recent inbound DM when omitted.

to
string

Explicit destination igsid; overrides contact/customer lookup.

body
required
string

Responses

Request samples

Content type
application/json
{
  • "customer_id": "160c0c4b-9966-4dc1-a916-8407eb10d74e",
  • "contact_id": "f245e2a3-e141-4d41-912c-b1c1f5bd5598",
  • "to": "string",
  • "body": "string"
}

Response samples

Content type
application/json
{
  • "data": {
    }
}

Get the Instagram DM timeline for a customer

Authorizations:
apiKeyAuth
query Parameters
customer_id
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "total_count": 0,
  • "has_more": true,
  • "message": "string"
}

Meta webhook verification handshake

Called by Meta when configuring the webhook subscription. Authenticated via the hub.verify_token query param matching INSTAGRAM_WEBHOOK_VERIFY_TOKEN, not member session.

Authorizations:
apiKeyAuth
query Parameters
hub.mode
string
hub.verify_token
string
hub.challenge
string

Responses

Receive inbound Instagram DMs and delivery/read callbacks

Authenticated via the X-Hub-Signature-256 header (HMAC of the body with INSTAGRAM_APP_SECRET), not member session. Inbound messages are matched to a Contact by resolving the sender's Instagram username. If no Contact matches, a new Customer (type "unknown") and Contact are auto-created using the sender's Instagram display name (falling back to their username, then their igsid if the username can't be resolved) so the conversation is never dropped. Responds 200 immediately and processes the payload after acknowledging, per Meta's requirements.

Authorizations:
apiKeyAuth

Responses

Public

Get a published form (no auth required)

path Parameters
form_id
required
string <uuid>

Responses

Submit a response to a form (no auth required)

path Parameters
form_id
required
string <uuid>
Request Body schema: application/json
required
required
object

Responses

Request samples

Content type
application/json
{
  • "answers": { }
}

Webhooks

Razorpay payment webhook

Request Body schema: application/json
object

Responses

Request samples

Content type
application/json
{ }

Versions

Get the current app client version

Responses

Response samples

Content type
application/json
{
  • "data": {
    }
}