Automation Engine
Shipping Rules
Automate carrier and service selection with intelligent rules. Define conditions based on weight, destination, dimensions, value, and more — then let the engine choose the optimal carrier for every shipment.
How It Works
Define Rules
Create condition-based or service group rules in the admin panel or via API
Assign to Users
Assign rules to Sub-Admins who can pass them to their customers
Ship with Rule ID
Customers use shipping_rule_id instead of carrier_id in API calls
Auto-Allocate
Engine evaluates conditions and returns the matched carrier + service
Rule Types
Available Condition Properties
These properties can be used in rule conditions to match against shipment data. Multiple conditions within a statement are evaluated as AND logic.
| Property | Type | Operators | Description |
|---|---|---|---|
destination_postcode | list | innot instarts with | Destination postal code or postcode range |
origin_postcode | list | innot instarts with | Origin/warehouse postal code |
destination_country | string | isis not | ISO 3166-1 two-letter country code |
total_weight | decimal | =<≤>≥ | Total shipment weight in kg or g |
max_dimension | decimal | =<≤>≥ | Largest dimension (L, W, or H) in cm |
package_count | integer | =<≤>≥ | Number of packages in the shipment |
shipment_value | decimal | =<≤>≥ | Total declared value of goods |
is_residential | boolean | isis not | Whether destination is residential |
warehouse_id | list | innot in | Source warehouse identifier |
item_sku | list | containsnot contains | SKU of items in the order |
Multi-Tenant Rule Hierarchy
Shipping rules integrate with the 3-tier pricing model. Each level of the hierarchy has different permissions for creating and managing rules.
- Create global shipping rules applied platform-wide
- Assign rules to specific Sub-Admins with markup
- Override any Sub-Admin or Customer rule
- View rule performance across all tenants
- Set auto-package rules for all carriers
- Create private rules for their own customers
- Customize inherited global rules (add conditions)
- Set carrier preferences and exclusions
- Define auto-package rules for their network
- View rule match statistics for their customers
- Use rules assigned by their Sub-Admin via API
- Pass shipping_rule_id instead of carrier_id
- View which rule was applied to each shipment
- Cannot create or modify rules
Rule Evaluation Flow
┌─────────────────────────────────────────────────────┐
│ Shipment Created │
│ shipping_rule_id: "rule_abc123" │
└──────────────────────┬──────────────────────────────┘
│
▼
┌────────────────┐
│ Statement 1 │
│ weight < 5kg │──── YES ──▶ Allocate: AusPost eParcel
│ postcode = 2* │
└───────┬────────┘
│ NO
▼
┌────────────────┐
│ Statement 2 │
│ weight < 25kg │──── YES ──▶ Allocate: Startrack Premium
│ postcode = 2* │
└───────┬────────┘
│ NO
▼
┌────────────────┐
│ DEFAULT │
│ │──────────▶ Allocate: TGE Road
└────────────────┘
After allocation:
┌──────────────────────────────────────────────┐
│ Apply 3-Tier Pricing Cascade │
│ base_cost → +master_markup → +sub_markup │
│ Store all cost tiers on shipment record │
└──────────────────────────────────────────────┘API Endpoints
Database Schema
-- Shipping Rules
CREATE TABLE shipping_rules (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
organization_id UUID NOT NULL REFERENCES organizations(id),
name VARCHAR(255) NOT NULL,
type VARCHAR(20) NOT NULL, -- 'condition' | 'service_group' | 'auto_package'
is_active BOOLEAN DEFAULT true,
priority INTEGER DEFAULT 0, -- Higher = evaluated first
-- Default action (condition rules)
default_carrier_id UUID REFERENCES carrier_connections(id),
default_service_code VARCHAR(100),
-- Scope
scope VARCHAR(20) DEFAULT 'private', -- 'global' | 'private'
assigned_to UUID[], -- Sub-Admin org IDs (global rules)
created_by UUID NOT NULL REFERENCES users(id),
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE(organization_id, name)
);
-- Rule Statements (conditions + actions)
CREATE TABLE shipping_rule_statements (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
rule_id UUID NOT NULL REFERENCES shipping_rules(id) ON DELETE CASCADE,
position INTEGER NOT NULL, -- Evaluation order
-- Conditions (JSON array of condition objects)
conditions JSONB NOT NULL DEFAULT '[]',
-- Example: [{"field":"total_weight","operator":"less_than","value":5,"unit":"kg"}]
-- Action (condition rules: allocate carrier)
carrier_id UUID REFERENCES carrier_connections(id),
service_code VARCHAR(100),
-- Action (service group rules: exclude services)
excluded_services JSONB DEFAULT '[]',
-- Action (auto-package rules: assign package)
package_id UUID REFERENCES predefined_packages(id),
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Service Group Priority List
CREATE TABLE shipping_rule_services (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
rule_id UUID NOT NULL REFERENCES shipping_rules(id) ON DELETE CASCADE,
carrier_id UUID NOT NULL REFERENCES carrier_connections(id),
service_code VARCHAR(100) NOT NULL,
priority INTEGER NOT NULL, -- 1 = highest priority
UNIQUE(rule_id, carrier_id, service_code)
);
-- Rule Match Log (for analytics)
CREATE TABLE shipping_rule_matches (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
rule_id UUID NOT NULL REFERENCES shipping_rules(id),
shipment_id UUID NOT NULL REFERENCES shipments(id),
statement_pos INTEGER, -- Which statement matched (NULL = default)
matched_at TIMESTAMPTZ DEFAULT NOW()
);Common Use Cases
Cheapest Carrier by Zone
Route metro shipments to Australia Post, regional to Startrack, and rural to TGE based on postcode ranges.
Weight-Based Carrier Split
Use satchel services for items under 5kg, pallet services for items over 25kg, and standard parcels for everything in between.
High-Value Shipment Routing
Automatically route shipments over $500 to carriers with built-in insurance and signature-on-delivery.
Auto-Package Selection
Automatically select the right satchel or box size based on total order weight, eliminating manual packaging decisions.
Express vs Economy
Use a service group with express services prioritized, but exclude them for heavy or oversized items to control costs.
Warehouse-Based Routing
Route shipments from your Sydney warehouse to one carrier and Melbourne warehouse to another based on negotiated rates.