Funnels & statuses
The sales pipeline — funnels, order statuses, allowed status transitions, contact fields required per status, and loss reasons.
Orders move through statuses. Statuses are grouped into funnels: separate pipelines, e.g. "Retail" and "Dealers". Every project has at least one funnel, and exactly one is the default.
Each status has a type that gives it meaning regardless of its name:
| Type | Meaning |
|---|---|
new |
Incoming orders |
active |
Work in progress |
done |
Won. Orders here count as revenue and towards a contact's total_spent |
canceled |
Lost. Moving an order here may require a loss reason |
A funnel can restrict moves between its statuses with a transition matrix. A status can require contact custom fields to be filled in before an order enters it. Both rules are enforced when an order's status changes, see Modify Order.
Field types follow the field notation.
Access
Every endpoint on this page requires the projects OAuth scope. The user must be a member of the project, and the
owner's subscription must be active. Otherwise the endpoint returns 404 RES_NOT_FOUND.
Any member can read funnels, statuses, transitions and loss reasons. Changing them requires can_edit_statuses.
Funnel Object
Funnel Structure
| Field | Type | Description |
|---|---|---|
| uuid | uuid | Funnel ID |
| project_uuid | uuid | Project ID. Only in Get Funnel |
| name | string | Name, 1–255 characters |
| order | integer | Sort position |
| is_default | boolean | Whether this is the default funnel. Exactly one funnel is the default |
| status_count | integer | Number of statuses in the funnel. Only in List Funnels |
| created_at | ISO8601 datetime | When the funnel was created |
Example Funnel
{
"uuid": "0198e7a0-0000-7000-8000-0000000000f1",
"name": "Retail",
"order": 1,
"is_default": true,
"status_count": 4,
"created_at": "2026-06-26T10:00:00.000Z"
}
List Funnels
GET /api/v1/projects/{project.uuid}/funnels
Returns the project's funnels, sorted by order.
Get Funnel
GET /api/v1/projects/{project.uuid}/funnels/{funnel.uuid}
Returns a single funnel, without status_count.
Create Funnel
POST /api/v1/projects/{project.uuid}/funnels
Creates an empty funnel. Add statuses to it with Create Status.
Requires can_edit_statuses.
JSON Params
| Field | Type | Description |
|---|---|---|
| name | string | 1–255 characters |
| order? | integer | Sort position. Default: after the last funnel |
| is_default? | boolean | Make this the default funnel. Default false |
Response
201 Created
{
"uuid": "0199a9e4-1b2c-7d3e-8f40-516273849506"
}
Modify Funnel
PATCH /api/v1/projects/{project.uuid}/funnels/{funnel.uuid}
Updates any of name, order, is_default. At least one must be present.
is_default: true moves the default here from the current default funnel. The default cannot be removed by sending
is_default: false to it; make another funnel the default instead.
Requires can_edit_statuses.
Response
204 No Content
Replace Funnel
PUT /api/v1/projects/{project.uuid}/funnels/{funnel.uuid}
Same as Modify Funnel, but name, order and is_default are all required.
Delete Funnel
DELETE /api/v1/projects/{project.uuid}/funnels/{funnel.uuid}
Deletes the funnel together with its statuses and their transitions. Rejected if it is the project's last funnel, or if
any non-deleted order is still in one of its statuses. Soft-deleted orders in it lose their status. Deleting the
default funnel makes the first remaining funnel, by order, the default.
Requires can_edit_statuses.
Response
204 No Content
Funnel Errors
| Status | Code | When |
|---|---|---|
| 400 | REQ_VALIDATION_FAILED |
The body does not match the schema |
| 400 | REQ_NO_DATA_PROVIDED |
Modify only: the body has no fields |
| 400 | FUNNEL_DEFAULT_REQUIRED |
is_default: false sent to the default funnel |
| 400 | FUNNEL_LAST_CANNOT_BE_DELETED |
Delete only: this is the project's only funnel |
| 400 | FUNNEL_HAS_ORDERS |
Delete only: the funnel still has orders; move or delete them first |
| 403 | AUTH_INSUFFICIENT_SCOPE |
The token lacks projects |
| 403 | AUTH_NO_PROJECT_ACCESS |
The user's role lacks can_edit_statuses |
| 404 | RES_NOT_FOUND |
The project or funnel does not exist |
Status Object
Status Structure
| Field | Type | Description |
|---|---|---|
| uuid | uuid | Status ID |
| project_uuid | uuid | Project ID. Only in Get Status |
| funnel_uuid | uuid | The funnel the status belongs to |
| name | string | Name, 1–255 characters |
| type | string | new, active, done or canceled |
| color | string | Colour name from the app palette, as for tags |
| order | integer | Position within the funnel |
| is_default | boolean | Default status of its funnel for new orders. At most one per funnel |
| is_default_widget | boolean | Status given to orders placed through the widget. At most one per project |
| required_field_names | array of string | Contact custom field names that must be filled in before an order enters this status |
| allowed_next | ?array of uuid | Statuses an order may move to from this one. null if the funnel has no transition matrix, meaning any move is allowed. Only in List Statuses |
| automations | array of string | Names of automations whose conditions refer to this status. Deleting the status silently stops them. Only in List Statuses |
| created_at | ISO8601 datetime | When the status was created |
Example Status
{
"uuid": "0198f1c0-2d4a-7e11-8b3f-1a2b3c4d5e6f",
"funnel_uuid": "0198e7a0-0000-7000-8000-0000000000f1",
"name": "In production",
"type": "active",
"color": "blue",
"order": 2,
"is_default": false,
"is_default_widget": false,
"required_field_names": [
"inn"
],
"allowed_next": [
"0198f1c0-2d4a-7e11-8b3f-1a2b3c4d5e70",
"0198f1c0-2d4a-7e11-8b3f-1a2b3c4d5e71"
],
"automations": [
"Write off materials"
],
"created_at": "2026-06-26T10:00:00.000Z"
}
List Statuses
GET /api/v1/projects/{project.uuid}/statuses
Returns all statuses of all funnels, sorted by order. Group them by funnel_uuid to build a board.
Get Status
GET /api/v1/projects/{project.uuid}/statuses/{status.uuid}
Returns a single status with required_field_names, without allowed_next and automations.
Create Status
POST /api/v1/projects/{project.uuid}/statuses
Creates a status at the end of a funnel.
Requires can_edit_statuses.
JSON Params
| Field | Type | Description |
|---|---|---|
| name | string | 1–255 characters |
| type? | string | Default new |
| color? | string | Up to 16 characters. Default blue |
| funnel_uuid? | uuid | Funnel to add to. Default: the project's default funnel |
| is_default? | boolean | Make this its funnel's default status. Default false |
| is_default_widget? | boolean | Make this the widget's status for new orders. Default false |
| required_field_names? | array of string | Contact custom field names, up to 64 characters each |
Setting is_default or is_default_widget clears the flag from the status that had it. order is always set to the
end of the funnel on creation.
Example Request
{
"name": "Measurement",
"type": "active",
"color": "amber",
"funnel_uuid": "0198e7a0-0000-7000-8000-0000000000f1",
"required_field_names": [
"delivery_address"
]
}
Response
201 Created
{
"uuid": "0199aa05-2c3d-7e4f-8051-627384950617"
}
Modify Status
PATCH /api/v1/projects/{project.uuid}/statuses/{status.uuid}
Updates any of name, type, color, order, is_default, is_default_widget, required_field_names. At least one
must be present. required_field_names, if sent, replaces the whole list. A status cannot be moved to another funnel.
Requires can_edit_statuses.
Response
204 No Content
Replace Status
PUT /api/v1/projects/{project.uuid}/statuses/{status.uuid}
Same as Modify Status, but name, type, color, order, is_default and is_default_widget are
required. required_field_names stays optional.
Delete Status
DELETE /api/v1/projects/{project.uuid}/statuses/{status.uuid}
Deletes the status with its transitions and field requirements. Orders in this status are left without a status: they drop off the boards and can only be given a status again through Modify Order. Automations that refer to the status stop firing. Move orders out first.
Requires can_edit_statuses.
Response
204 No Content
Status Errors
| Status | Code | When |
|---|---|---|
| 400 | REQ_VALIDATION_FAILED |
The body does not match the schema |
| 400 | REQ_NO_DATA_PROVIDED |
Modify only: the body has no fields |
| 403 | AUTH_INSUFFICIENT_SCOPE |
The token lacks projects |
| 403 | AUTH_NO_PROJECT_ACCESS |
The user's role lacks can_edit_statuses |
| 404 | RES_NOT_FOUND |
The project, status, or (on create) funnel_uuid does not exist |
Status Transitions
A transition allows an order to move from one status to another. Transitions are configured per funnel:
- A funnel with no transitions allows any move between its statuses.
- Once a funnel has at least one transition, only listed moves are allowed. Keeping the same status is always allowed.
- Moving an order to a status in another funnel is always allowed.
Transition Structure
| Field | Type | Description |
|---|---|---|
| from_status_uuid | uuid | From status |
| to_status_uuid | uuid | To status |
List Transitions
GET /api/v1/projects/{project.uuid}/statuses/transitions
Returns all transitions of all funnels, as an array of transition objects.
Replace Funnel Transitions
PUT /api/v1/projects/{project.uuid}/statuses/transitions
Replaces every transition of one funnel. Other funnels are not affected. Send an empty transitions array to remove
the matrix and allow every move again.
Requires can_edit_statuses.
JSON Params
| Field | Type | Description |
|---|---|---|
| funnel_uuid | uuid | The funnel |
| transitions | array of transition | Allowed moves; both statuses must be in this funnel |
Example Request
A linear pipeline New → Measurement → In production → Completed, with Canceled reachable from the first two:
{
"funnel_uuid": "0198e7a0-0000-7000-8000-0000000000f1",
"transitions": [
{
"from_status_uuid": "<new>",
"to_status_uuid": "<measurement>"
},
{
"from_status_uuid": "<measurement>",
"to_status_uuid": "<in_production>"
},
{
"from_status_uuid": "<in_production>",
"to_status_uuid": "<completed>"
},
{
"from_status_uuid": "<new>",
"to_status_uuid": "<canceled>"
},
{
"from_status_uuid": "<measurement>",
"to_status_uuid": "<canceled>"
}
]
}
Response
204 No Content
Errors
| Status | Code | When |
|---|---|---|
| 400 | REQ_VALIDATION_FAILED |
The body does not match the schema, or a status is not in this funnel |
| 403 | AUTH_INSUFFICIENT_SCOPE |
The token lacks projects |
| 403 | AUTH_NO_PROJECT_ACCESS |
The user's role lacks can_edit_statuses |
| 404 | RES_NOT_FOUND |
The project does not exist, or the funnel has no statuses |
Loss Reason Object
Why an order was lost. If a project has at least one loss reason, moving an order into a canceled-type status
requires one, see Modify Order. With no loss reasons configured, none is required.
Loss Reason Structure
| Field | Type | Description |
|---|---|---|
| uuid | uuid | Loss reason ID |
| name | string | Name, 1–255 characters |
| order | integer | Sort position |
| created_at | ISO8601 datetime | When the loss reason was created |
Example Loss Reason
{
"uuid": "0199a1bb-0001-7000-8000-000000000001",
"name": "Too expensive",
"order": 1,
"created_at": "2026-08-11T09:02:00.000Z"
}
List Loss Reasons
GET /api/v1/projects/{project.uuid}/loss-reasons
Returns the project's loss reasons, sorted by order.
Create Loss Reason
POST /api/v1/projects/{project.uuid}/loss-reasons
Requires can_edit_statuses.
| Field | Type | Description |
|---|---|---|
| name | string | 1–255 characters, trimmed |
| order? | integer | Sort position. Default: after the last reason |
201 Created with {"uuid": "..."}.
Modify Loss Reason
PATCH /api/v1/projects/{project.uuid}/loss-reasons/{reason.uuid}
Updates name and/or order. At least one must be present. 204 No Content.
Requires can_edit_statuses.
Delete Loss Reason
DELETE /api/v1/projects/{project.uuid}/loss-reasons/{reason.uuid}
Deletes the loss reason. Orders that had it keep loss_reason_note but lose loss_reason_uuid. 204 No Content.
Requires can_edit_statuses.
Loss Reason Errors
| Status | Code | When |
|---|---|---|
| 400 | REQ_VALIDATION_FAILED |
The body does not match the schema |
| 400 | REQ_NO_DATA_PROVIDED |
Modify only: the body has no fields |
| 403 | AUTH_INSUFFICIENT_SCOPE |
The token lacks projects |
| 403 | AUTH_NO_PROJECT_ACCESS |
The user's role lacks can_edit_statuses |
| 404 | RES_NOT_FOUND |
The project or loss reason does not exist |