Rules: three shapes, not two
/api/rest/rules is a general-purpose object for account-specific if-this-then-that policies (see Rule in the glossary), but the fields you populate depend on the rule’s type — mixing them up produces a rule that silently never fires.
- Action-only — no condition fields at all: only
actionType+actionValueare set, and the rule’stypeitself determines when it applies. This is the most common shape (e.g.ON_CREATION_FROM_EMAILrules) — don’t assume every rule needs a condition or a DSL expression. - DSL expression pair — used by
type: "CUSTOMER_INVOICE_EXCEPTION"rules:conditionExpression(when the rule applies — an expression likeShipment.mode = 'FTL' AND Invoice.totalAmount > 1000, or the literalsALWAYS/NEVER) andvalidationExpression(what to check —REQUIRE Document WHERE ...orVALIDATE ... = ..., see the worked example below). ForCUSTOMER_INVOICE_EXCEPTIONrules, send both DSL fields — a DSL-driven rule that carries only one of them is rejected with a400. The exception is config-managed exception types — ones evaluated in application code rather than by the DSL, which are allowed to carry NULL expressions and act as on/off toggles. That exempt set has been widened several times, so don’t assume a given type is or isn’t exempt: send bothconditionExpressionandvalidationExpressionunless you know the type is config-managed. If a toggle-style rule returns an unexpected400, the response names thecheck_rule_dsl_formatconstraint — that’s the signal the type you’re writing is not exempt; ask support@upwell.com which types currently are. - Structured criteria (
criteriaObject/criteriaField/criteriaOperator/criteriaValue) exist in the API but are not the mechanism rules are built on — treat them as legacy and use the shapes above instead.
Example: validate a customer invoice against its customer rate confirmation
Once customer rate confirmations are flowing in, a shipper rule (aCUSTOMER_INVOICE_EXCEPTION-type rule using the DSL expression pair) can hold a customer invoice for review when its amount doesn’t match the customer’s rate confirmation. The rule compares the parsed customer rate confirmation total against the shipment’s customer total rate — both customer-side amounts, stored in cents:
CUSTOMER_INVOICE_EXCEPTION and stays in Needs Review instead of going out to the customer. The comparison only ever reads CUSTOMER_RATE_CONFIRMATION documents — it never compares against a CARRIER_RATE_CONFIRMATION.
