Skip to content
Knowledge ERP Docs

API Reference ↗
Automation

Automation Rules

A saved "when this happens, do that" workflow — a trigger that watches for an event, optional conditions that must pass, and one or more actions that fire automatically.

An automation rule is a standing "when this happens, do that" instruction. You define a trigger (the event to watch for), optional conditions (tests that must pass), and an ordered list of actions (what to do), and Knowledge ERP runs them for you — no one has to remember to. A rule might email a customer when their invoice is 30 days unpaid, raise a purchase order when stock dips below its reorder point, or ping a Slack endpoint when a work order is finished.

A rule fires only when its trigger matches and every condition passes. With no conditions, the trigger alone is enough. The actions then run in order, and the whole run is recorded as a log — success or failure.

A rule's emails, in-app notifications, webhook calls, text messages and surveys wait until the change that triggered it has been saved, and are not sent if saving it fails. Rules on Purchase order submitted are the exception: they run as an order is submitted, before its approval and spending checks, so their messages are sent even when the submission is then refused by one of them.

Rules are managed in the Automation Builder under Automation → Automation Rules.

A rule's actions that create records, Create Purchase Order, Create Task and Send Survey, run at most once for each change that sets the rule off. A Purchase order created rule that creates a purchase order creates one for the order someone created, and none for the order it created itself; several such rules feeding each other each create once. A rule's other actions, such as Require Approval, notifications, email, webhooks and text messages, run every time, so a rule that requires approval holds every order its conditions match: the one someone created and each one rules created from it, even if that same rule creates orders too. A run with nothing left to do is logged as Skipped with the reason; a run that skipped only its creating actions lists them in its log.

This works inside Knowledge ERP. A loop that goes out and comes back in, such as a webhook to another system that then creates an order through the API, is not stopped.

The three parts of a rule #

Every rule is made of the same three pieces:

  • Trigger — the event that wakes the rule up. Triggers are grouped by module: Inventory (stock falls below threshold, checked-out item overdue), Sales (invoice overdue, invoice unpaid for N days, new sales order), Manufacturing (work order overdue, work order status changes), Purchasing (new purchase order), CRM (opportunity moves to a stage), Rentals (rental overdue), and Scheduled (daily, weekly, or monthly). Some triggers carry extra trigger configuration — e.g. Invoice unpaid for N days asks how many days, Work order status changes lets you pick which statuses fire it, and the weekly and monthly schedules ask for a day of the week or month. A scheduled rule runs once a day at its time of day, on its day, all in your account's time zone (set in Account Settings), within about 15 minutes of that time.
  • Conditions — optional field/operator/value tests against the trigger's context. The field is a context field name like amount_due, status, or days_overdue (for overdue checkouts and rentals, whole days counted on the checkout's or rental's location calendar: its time zone when it has one, otherwise your account's; for an overdue work order, on its output Location's calendar, and the overdue work order trigger counts a work order as overdue after the day it was due is over there); operators are equals, does not equal, greater/less than (or equal), and contains. All conditions must pass for the rule to fire.
  • Actions — what runs when the rule fires, in order. The available actions are Send Email, Send SMS, Notify Users (in-app + email to selected users), Create Task, Create Purchase Order, Call Webhook, Require Approval, and Send Survey (send a survey invitation to an email address — leave the recipient blank to send to the customer on the triggering record).

Create Purchase Order: where the order goes #

The Create Purchase Order action raises a draft order for one product from one vendor, at the quantity and unit price you set. It orders into:

  1. the Receiving Location set on the action, if there is one;
  2. otherwise, the Location the trigger happened at, for triggers that have one, such as Low stock at a Location;
  3. otherwise, your account's only Location.

If your account has more than one Location, the action must name one when the trigger has no Location, and also when you can't raise purchase orders across the whole account, because the trigger's Location could be one where you can't order. The rule can't be saved without it. The Receiving Location list offers the Locations where you can raise purchase orders yourself. Enabling a rule asks the same as saving it; anyone who can edit rules can disable one. When a rule runs and none of the three gives a Location, it orders nothing, and its log says why.

A unit price can be up to $42,949,672.95, and a quantity from 0.001 up to 999,999.9999, which is what a purchase order line holds.

A Low stock rule waits for its own open order. When a Low stock rule has already raised an order for a product into a Location, it does not raise another for that product into that Location while that order is still open, meaning Draft, Submitted or Partially received. Once the order is Received or Cancelled, the rule can raise a new one. This is how a rule that always orders into one Location, Central for example, stops raising an order every day while the stores it serves still show as short. Another rule's open order does not hold this rule back, a different product or a different Location is still ordered, and a rule on another trigger raises an order each time it runs. A run that is held back still shows as successful in the rules list, and the rule's log says the order is still open.

Call Webhook destinations #

The Call Webhook action posts the trigger's context to a URL you supply, and it is our server that makes the call — so the address has to be one we are willing to dial. Two rules, applied when you save the rule and again each time it fires:

  • It must be https://. The payload carries customer names, addresses and notes, and plain http:// puts them on the wire in clear.
  • It must be a public address. Loopback (127.0.0.1, localhost), private ranges (10.x, 192.168.x, 172.16–31.x) and link-local addresses — including the cloud metadata endpoint 169.254.169.254 — are refused.

Saving a rule with an address that fails either check shows an error on the Webhook URL field. The check runs again at send time, because a hostname can resolve to a different address later than it did when you saved it; a rule whose destination has become unsafe is logged as a skipped action rather than called. A delivery is an answer in the 2xx range. Redirects are not followed, so a destination that answers with a 302, like one that answers with an error, counts as a failed delivery, and the log records the answer it gave.

To send to a service inside your own network, put a public HTTPS endpoint in front of it rather than pointing the rule at an internal address.

Email, SMS, and task fields support {{field_name}} placeholders that pull values straight from the trigger's context — e.g. Hi {{customer_name}}, invoice {{invoice_number}} is overdue, or {{sku_name}} is running low at {{location_name}} for Low stock, which runs once per Location. Each field lists the placeholders its trigger provides. A placeholder the trigger does not provide fails the run and says which one was missing, rather than sending the raw {{token}} text — so a mistyped placeholder shows up as a failed run in the log instead of a survey no customer could ever receive. Spaces inside the braces are fine ({{ customer_name }}), and a placeholder the trigger provides but has no value for (a booking made without a phone number, say) is left blank.

In emails and in-app notifications, what a placeholder puts in is shown as plain text: a customer's name that contains *, # or a link appears as those characters (in an email, a line break in it can show as a space). Formatting and links you write in the rule itself work as usual.

Building a rule #

From Automation → Automation Rules → New, fill in the form top to bottom:

  • Name and an optional description — what the rule is for. Required name.
  • Trigger type — pick from the grouped list. If the trigger needs extra setup, a Trigger Configuration section appears below it with the right fields.
  • Enabled — on by default; see enabling and disabling.
  • Conditions — add as many field/operator/value rows as you need, or leave the section empty to always fire.
  • Actions — add at least one action and choose its type; the form then shows only the fields that action needs (recipient and body for an email, vendor/Product/ quantity for a purchase order, URL and payload for a webhook, and so on). Drag to reorder — they run in the order shown. A Call Webhook URL must be a public https:// address — see Call Webhook destinations.

The Require Approval action is special: instead of acting immediately, it opens an approval request and waits for a person to approve or reject before anything downstream proceeds. It also holds the record itself. On a purchase order it marks the order as needing approval. The order stays an editable Draft, so its lines can still be added and changed; when it is submitted, it waits for approval instead of going to the vendor, and is locked while it waits. The mark stays on the order, so an order withdrawn or unlocked and submitted again waits for approval again.

Put spend thresholds on Purchasing: Purchase order submitted, not on New purchase order created. A PO is created header-only and its lines are added afterwards, so a Total amount (home currency) >= 100000 condition on the created trigger is measured against an order with no total yet and can never match. The submitted trigger fires with the total recomputed from the order's lines.

The purchase order triggers offer two totals: Total amount (home currency), the order's total in your home currency at the higher of the order's exchange rate and the stored ECB rate nearest its date (the figure its purchase and approval limits weigh), and Total amount (order currency), in the currency the order is in. Put a spend threshold on the home currency one. A rule that already had a condition on the total was moved to it in this release. While purchase orders are in your home currency only, the two are the same.

The rule's home currency total is not always the same figure as the total_amount_home the API and webhooks return for an order: those are at the order's own exchange rate, and the rule's is the figure the limits weigh.

Enabling and disabling #

A rule's Enabled toggle decides whether it runs at all. Turn a rule off to pause it without losing its configuration, its history, or its logs — far safer than deleting and rebuilding it. Disabled rules simply never fire. The rules list shows an Active indicator, the trigger, a Runs count, and when the rule last ran (or Never), and can be filtered by trigger type.

Deleting a rule soft-deletes it: the rule disappears from the list, but its logs and any approval requests it created are retained for the record.

Execution logs #

Every time a rule fires, Knowledge ERP writes an automation rule log — a record of that single run. Logs are how you answer "did my rule actually do anything, and what happened?"

Each log captures:

  • the rule that ran,
  • a status — Pending, Success, Failed, or Skipped,
  • the context the rule saw (the trigger's data at the moment it fired),
  • a result payload describing what each action did or why it didn't, and
  • the triggered-at timestamp.

You can read logs, and Knowledge ERP keeps them; you can't edit or delete one. A Pending log belongs to a run whose messages are held for the change to be saved. Once they are sent, the log shows Success, with each message's outcome in its result (a webhook's response code, for example). A log that stays Pending means the outcome of its messages was never recorded, for example because the app stopped before sending them. A Skipped log means the trigger matched but the conditions didn't pass, or that the rule's only actions create records and it had already created them for the change that set it off. A Failed log records an action that errored, or a message that could not be sent (a webhook destination that could not be reached, say), along with the reason in its result. When an action errors partway through a rule, what the actions before it did is kept, their messages are sent, and the log lists them beside the reason. You can pull logs over the API filtered by rule or status — see the Automation Rule Logs API.

How it relates to approvals and the builder #

Automation rules live inside the broader Automation Builder, which is the home for everything event-driven in Knowledge ERP. When a rule uses the Require Approval action, it produces an approval request — a hold that a designated user must clear before the workflow continues. That keeps powerful automations (like auto-creating a purchase order) on a human leash where you want one.

Doing it from the API #

The API uses _id field names (never _uuid). Prices on the purchase-order action are entered in dollars on the form; over the API you send the JSON shapes your actions expect under actions.

# List rules, optionally filtered by trigger type and enabled state
curl "https://your-domain.com/api/v1/automation/rules?trigger_type=invoice_unpaid_days&enabled=true" \
  -H "Authorization: Bearer $TOKEN"

# Create a rule: email the customer when an invoice is 30 days unpaid
curl -X POST "https://your-domain.com/api/v1/automation/rules" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Nudge 30-day unpaid invoices",
    "trigger_type": "invoice_unpaid_days",
    "trigger_config": {"days": 30},
    "conditions": [{"field": "amount_due", "operator": ">", "value": "0"}],
    "actions": [
      {"type": "send_email", "to": "ar@your-domain.com", "subject": "Invoice past due", "body": "{{customer_name}} has not paid invoice {{invoice_number}} in {{days_unpaid}} days."}
    ]
  }'

# Review what a rule has done (logs are read-only)
curl "https://your-domain.com/api/v1/automation/rule-logs?rule_id=RULE_ID&status=failed" \
  -H "Authorization: Bearer $TOKEN"

Logs cannot be created, updated, or deleted through the API — they only ever appear as a side effect of a rule running.