Documentation / Automations

Automations

Event-driven automations — events, conditions and actions, outgoing webhooks with signatures, the run log, and the endpoints to manage automations.

An automation runs actions when an event happens in the project and the event matches the automation's conditions. For example: when an order moves to "In production", write off its materials from the default warehouse and create a task for the workshop.

Every run is recorded in the automation's run log, whether it succeeded or failed.

Field types follow the field notation.

Access

Every endpoint on this page requires both the projects and automations OAuth scopes. 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.

All endpoints require can_edit_project; the project owner bypasses this check. (The can_view_automations and can_edit_automations permission bits are reserved and not checked yet.)

Automation Object

Automation Structure

Field Type Description
uuid uuid Automation ID
name string Name, 1–255 characters. Shown in order journals next to what it did
is_active boolean Inactive automations never run
event string The event that triggers it
conditions object Event-specific filter, see Events
actions array of action objects Run in order
created_at ISO8601 datetime When the automation was created
updated_at ISO8601 datetime When the automation was last changed

Action Structure

Field Type Description
type string One of the action types
params object Action parameters, see Actions

Example Automation

{
  "uuid": "0199b07c-93a4-75b6-c7d8-e9f0a1b2c3d4",
  "name": "Start production",
  "is_active": true,
  "event": "order_status_changed",
  "conditions": {
    "status_uuid": "0198f1c0-2d4a-7e11-8b3f-1a2b3c4d5e6f"
  },
  "actions": [
    {
      "type": "warehouse_spend_bom",
      "params": {
        "target": "materials",
        "warehouse": "default"
      }
    },
    {
      "type": "create_task",
      "params": {
        "title": "Cut and assemble",
        "assignee": "0198f0b2-3c4d-7e5f-8a6b-7c8d9e0f1a2b",
        "due_in_days": 2
      }
    },
    {
      "type": "send_webhook",
      "params": {
        "url": "https://erp.acme.example/hooks/configo",
        "secret": "s3cr3t"
      }
    }
  ],
  "created_at": "2026-09-10T08:00:00.000Z",
  "updated_at": "2026-09-10T08:00:00.000Z"
}

Events

Event Fires when Conditions Payload
order_created A new order is saved — from the widget, the API, or the app none order_uuid, status_uuid (its initial status), entity_type: "order", entity_uuid
order_status_changed An order is moved to another status (by a user, the API, or the app). Not when an order is created status_uuid (required): the status the order moved to order_uuid, status_uuid, entity_type: "order", entity_uuid
task_overdue An open task passes its due date. Checked every 15 minutes; fires once per due date none task_uuid, entity_type, entity_uuid (the task's link), order_uuid (if linked to an order)
scheduled Every day at 09:00 server time; weekly on Mondays, monthly on the 1st frequency (required): daily, weekly or monthly frequency

A condition matches when the payload has the same value under the same key.

Transactions. order_status_changed automations run inside the same transaction as the status change. If any of them fails, for example a write-off without enough stock, the status change is rolled back and the API returns the error (409 ORDER_INSUFFICIENT_STOCK). order_created automations run after the order is saved, each on its own: a failure never undoes the order and shows up only in the run log. Time-driven events also run each automation on its own, so one failure does not stop the others.

Actions

Which actions are available depends on the event. An action not offered under an event is rejected on save.

Action order_created order_status_changed task_overdue scheduled
warehouse_spend_bom ✓
warehouse_income_product ✓
create_task ✓ ✓ ✓ ✓
change_responsible ✓ ✓ ✓
send_email ✓ ✓ ✓
send_webhook ✓ ✓ ✓ ✓

warehouse_spend_bom

Writes off stock for the order.

Param Type Description
target? string materials (default): the materials of every order product, by bill of materials × quantity. products: the finished products themselves
warehouse string A warehouse uuid, or default for the project's default warehouse

Fails, and with it the status change, if any item lacks stock. Movements are recorded in the warehouse history as spend and in the order journal as automation_warehouse_movement.

warehouse_income_product

Puts the order's finished products into stock, e.g. when production is complete.

Param Type Description
target? string products (the only option)
warehouse string A warehouse uuid, or default

create_task

Creates a task, linked to the event's entity (the order, or the overdue task's order or contact).

Param Type Description
title string Task title. Required
assignee? string A member uuid, or inherit (default) for the order's responsible member. Under scheduled and order_created, inherit is not available: give a member (a new order usually has no responsible yet)
due_in_days? integer Due date, days from now; ≥ 0. Default 1

change_responsible

Makes another member responsible for the order. Under task_overdue it works only for tasks linked to an order.

Param Type Description
member uuid Project member. Required

send_email

Sends an email template to the contact the event is about. The email is sent only after the transaction commits.

Param Type Description
template uuid Email template. Required

send_webhook

POSTs the event to your URL. The request is sent only after the transaction commits, so a rolled-back event is never reported.

Param Type Description
url string http or https URL. Required
secret? string If set, requests are signed, see below

See Webhooks.

Webhooks

Webhook Request

POST /hooks/configo HTTP/1.1
Host: erp.acme.example
Content-Type: application/json
User-Agent: ConfigoWebhook/1.0
X-Configo-Signature: sha256=5d41402abc4b2a76b9719d911017c592...
{
  "event": "order_status_changed",
  "project_uuid": "0198e7a0-0000-7000-8000-000000000001",
  "automation": {
    "uuid": "0199b07c-93a4-75b6-c7d8-e9f0a1b2c3d4",
    "name": "Start production"
  },
  "payload": {
    "order_uuid": "0199a4e2-7b1c-7c3e-9d2a-5f4e8b1c0a11",
    "status_uuid": "0198f1c0-2d4a-7e11-8b3f-1a2b3c4d5e6f",
    "entity_type": "order",
    "entity_uuid": "0199a4e2-7b1c-7c3e-9d2a-5f4e8b1c0a11"
  },
  "sent_at": "2026-10-01T11:02:41.512Z"
}

payload is the event payload. The webhook carries IDs only; fetch the order or task through the API if you need its details.

Verifying the signature

With a secret, X-Configo-Signature is sha256= followed by the hex HMAC-SHA256 of the raw request body with the secret as key. Compute it over the bytes you received, before parsing the JSON, and compare in constant time:

import {createHmac, timingSafeEqual} from 'node:crypto'

function verify(rawBody, header, secret) {
    const expected = 'sha256=' + createHmac('sha256', secret).update(rawBody).digest('hex')
    return header && header.length === expected.length && timingSafeEqual(Buffer.from(header), Buffer.from(expected))
}

Delivery

  • Respond with any 2xx status within 10 seconds. Anything else, a timeout, or a network error counts as a failure.
  • Failed deliveries are retried up to 5 attempts in total, with exponential backoff starting at 5 seconds.
  • Redirects are not followed.
  • URLs resolving to private, loopback, link-local or CGNAT addresses are refused.
  • Delivery is at least once: deduplicate by automation.uuid + payload + sent_at if that matters to you.

List Automations

GET /api/v1/projects/{project.uuid}/automations

Returns the project's automations, newest first.

Get Automation

GET /api/v1/projects/{project.uuid}/automations/{automation.uuid}

Create Automation

POST /api/v1/projects/{project.uuid}/automations

JSON Params

Field Type Description
name string 1–255 characters
event string An event
conditions? object Default {}. Required keys depend on the event
actions? array Default []
is_active? boolean Default true

The automation is checked against the event catalog: the event must exist, required conditions must be set, every action must be offered under the event, and every required parameter must be filled in. Parameters with a default (warehouse: "default", assignee: "inherit") count as filled. References such as a member or template uuid are checked only when the automation runs; a stale one shows up as a failed run.

Response

201 Created with {"uuid": "..."}.

Modify Automation

PATCH /api/v1/projects/{project.uuid}/automations/{automation.uuid}

Updates any of name, is_active, event, conditions, actions. At least one must be present. conditions and actions replace the stored value. The result is checked against the catalog as on create. To switch an automation off, send {"is_active": false}.

PUT requires name and event; the other fields are optional.

204 No Content.

Delete Automation

DELETE /api/v1/projects/{project.uuid}/automations/{automation.uuid}

Deletes the automation and its run log. 204 No Content.

List Automation Runs

GET /api/v1/projects/{project.uuid}/automations/{automation.uuid}/runs

Returns runs newest first, 50 per page (page? query param, from 1). Runs older than 30 days are deleted.

Run Structure

Field Type Description
uuid uuid Run ID
status string success or failed
error ?string Why it failed: an error code such as ORDER_REQUIRED, WEBHOOK_URL_INVALID, or a JSON list of stock shortages
context object {event, payload}; deferred: true if an email or webhook failed to be queued after commit
created_at ISO8601 datetime When it ran

A success run means the actions completed and emails and webhooks were queued. A webhook that later fails to deliver does not change the run's status.

[
  {
    "uuid": "0199b1aa-0000-7000-8000-000000000001",
    "status": "failed",
    "error": "[{\"material_uuid\":\"0199a2c0-7a1b-7c2d-8e3f-a0b1c2d3e4f5\",\"needed\":12.5,\"available\":8,\"item_type\":\"material\",\"name\":\"Blackout 605\",\"unit\":\"sm\"}]",
    "context": {
      "event": "order_status_changed",
      "payload": {
        "order_uuid": "0199a4e2-7b1c-7c3e-9d2a-5f4e8b1c0a11",
        "status_uuid": "0198f1c0-2d4a-7e11-8b3f-1a2b3c4d5e6f",
        "entity_type": "order",
        "entity_uuid": "0199a4e2-7b1c-7c3e-9d2a-5f4e8b1c0a11"
      }
    },
    "created_at": "2026-10-01T11:02:41.000Z"
  }
]

Errors

Status Code When
400 REQ_VALIDATION_FAILED The body does not match the schema
400 REQ_NO_DATA_PROVIDED Modify: the body has no fields
400 AUTOMATION_INVALID The automation does not fit the event catalog; reason says why, see below
403 AUTH_INSUFFICIENT_SCOPE The token lacks projects or automations
403 AUTH_NO_PROJECT_ACCESS The user's role lacks can_edit_project
404 RES_NOT_FOUND The project or automation does not exist

AUTOMATION_INVALID carries a reason object:

reason.kind Other fields Meaning
unknown_event event No such event
condition_required condition A required condition is missing
action_not_allowed event, action_type The action is not offered under this event
param_required action_type, param A required action parameter is missing
param_not_allowed action_type, param The value is not available under this event, e.g. assignee: "inherit" under scheduled or order_created
{
  "id": 4010,
  "code": "AUTOMATION_INVALID",
  "message": "The automation does not match the event catalog: unknown event, an action unavailable for it, or a missing required value.",
  "reason": {
    "kind": "action_not_allowed",
    "event": "scheduled",
    "action_type": "warehouse_spend_bom"
  }
}