> ## Documentation Index
> Fetch the complete documentation index at: https://docs.liberate.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Decision table node

# Decision Table Node

The **Decision Table Node** lets you map inputs to outputs using a visual table—no code required. Use it for routing claims, assigning adjusters, determining priority levels, or any scenario where clear rules map conditions to outcomes.

> [!NOTE]
>
> Decision Tables are ideal when you have well-defined business rules that can be expressed as "if this, then that" logic. They're easier to maintain than code and more readable than complex JSONata expressions.

## Overview

Use a Decision Table Node when you need to:

* Route claims to different adjusters based on type or amount
* Assign priority levels based on multiple factors
* Map codes to descriptions or categories
* Determine next steps based on customer inputs
* Apply business rules that non-developers need to update

***

## When to Use Decision Table vs. Other Nodes

| Task | Best Node |
| - | - |
| Simple if/else with 2-3 conditions | Mapping Node (JSONata ternary) |
| Multiple conditions with clear rules | **Decision Table Node** |
| Complex calculations | Code Node |
| Fuzzy matching or interpretation | AI Prompt Node |
| Static reference data lookup | Entity Table Node |
| Rules that business users maintain | **Decision Table Node** |

> [!TIP]
>
> Decision Tables shine when business users need to update rules without developer involvement. The visual table format is intuitive and reduces errors.

***

## Configuration

Click on a Decision Table Node to open its configuration panel.

### Basic Settings

| Setting | Description |
| - | - |
| **Title** | Descriptive name for the node |
| **Input Columns** | Conditions to evaluate (from context) |
| **Output Columns** | Values to set when conditions match |
| **Rules** | Rows defining condition-to-output mappings |

### Table Structure

A Decision Table has two sections:

```
┌─────────────────────────────────────┬────────────────────────────┐
│          INPUT COLUMNS              │       OUTPUT COLUMNS       │
│    (Conditions to Match)            │    (Values to Set)         │
├─────────────────────────────────────┼────────────────────────────┤
│  claimType  │  amount   │  region   │  priority  │  assignee    │
├─────────────┼───────────┼───────────┼────────────┼──────────────┤
│  fire       │  *        │  *        │  high      │  senior_adj  │
│  water      │  over 50k │  *        │  high      │  senior_adj  │
│  water      │  under 50k│  *        │  medium    │  auto_adj    │
│  theft      │  *        │  *        │  medium    │  auto_adj    │
│  *          │  *        │  *        │  standard  │  queue       │
└─────────────┴───────────┴───────────┴────────────┴──────────────┘
```

***

## Input Columns

Input columns define the conditions to evaluate. Each column references a field from the workflow context.

### Configuring Input Columns

| Setting | Description | Example |
| - | - | - |
| **Column Name** | Display label | Claim Type |
| **Context Path** | Path to context field | claimType or claim.type |
| **Data Type** | Type of comparison | String, Number, Boolean |

### Match Operators

| Operator | Meaning | Example | Matches |
| - | - | - | - |
| `*` | Any value (wildcard) | `*` | Everything |
| value | Exact match | fire | Only "fire" |
| `> N` | Greater than | `> 50000` | 50001, 100000, etc. |
| `>= N` | Greater than or equal | `>= 50000` | 50000, 50001, etc. |
| `< N` | Less than | `< 10000` | 9999, 5000, etc. |
| `<= N` | Less than or equal | `<= 10000` | 10000, 9999, etc. |
| `!= value` | Not equal | `!= fire` | water, theft, auto |
| `in [a,b,c]` | In list | `in [CA,TX,FL]` | CA, TX, or FL |
| `not in [a,b]` | Not in list | `not in [CA,TX]` | Any except CA, TX |

***

## Output Columns

Output columns define the values set when a rule matches. These values are added to the workflow context.

### Configuring Output Columns

| Setting | Description | Example |
| - | - | - |
| **Column Name** | Display label | Priority |
| **Context Path** | Where to store output | priority or routing.priority |
| **Data Type** | Type of output value | String, Number, Boolean |

***

## Rule Evaluation

### How Rules Are Processed

1. Rules are evaluated **top to bottom**
2. **First matching rule wins** (subsequent rules are skipped)
3. If no rules match, outputs are set to null (or default values if configured)

> [!WARNING]
>
> Order matters! Place more specific rules above general rules. Put your catch-all rule (wildcard in all inputs) at the bottom.

### Example Evaluation

Context:

```json theme={null}
{
  "claimType": "water",
  "amount": 75000
}
```

Table:

| claimType | amount | priority | assignee |
| - | - | - | - |
| fire | any | high | senior\_adj |
| water | over 50000 | high | senior\_adj |
| water | 50000 or less | medium | auto\_adj |
| any | any | standard | queue |

**Evaluation:**

1. Row 1: claimType equals fire? No, skip
2. Row 2: claimType equals water AND amount over 50000? Yes, MATCH
3. Output: priority is high, assignee is senior\_adj

***

## Insurance Examples

### Route Claims by Type and Amount

Assign adjusters based on claim characteristics.

**Input Columns:**

| Column | Context Path |
| - | - |
| Claim Type | claimType |
| Amount | estimatedAmount |
| Has Injuries | injuriesReported |

**Output Columns:**

| Column | Context Path |
| - | - |
| Priority | priority |
| Assignee | assignedTo |
| SLA Hours | slaHours |

**Rules:**

| Claim Type | Amount | Has Injuries | Priority | Assignee | SLA Hours |
| - | - | - | - | - | - |
| any | any | true | critical | senior\_adjuster | 4 |
| fire | any | any | high | senior\_adjuster | 8 |
| water | over 50000 | any | high | senior\_adjuster | 12 |
| auto | over 25000 | any | high | senior\_adjuster | 12 |
| water | 50000 or less | any | medium | adjuster\_pool | 24 |
| auto | 25000 or less | any | medium | adjuster\_pool | 24 |
| theft | any | any | medium | adjuster\_pool | 24 |
| any | any | any | standard | adjuster\_pool | 48 |

**Result in context:**

```json theme={null}
{
  "claimType": "water",
  "estimatedAmount": 75000,
  "injuriesReported": false,
  "priority": "high",
  "assignedTo": "senior_adjuster",
  "slaHours": 12
}
```

***

### Determine State-Specific Requirements

Apply different rules based on state regulations.

**Input Columns:**

| Column | Context Path |
| - | - |
| State | policyState |
| Claim Type | claimType |

**Output Columns:**

| Column | Context Path |
| - | - |
| Requires Licensed Adjuster | requiresLicensedAdjuster |
| Regulatory Filing Required | regulatoryFiling |
| Max Response Days | maxResponseDays |

**Rules:**

| State | Claim Type | Licensed Adjuster | Regulatory Filing | Max Response Days |
| - | - | - | - | - |
| FL | any | true | true | 14 |
| TX | any | true | false | 15 |
| CA | fire | true | true | 30 |
| CA | any | true | false | 30 |
| NY | any | true | false | 35 |
| any | any | false | false | 30 |

***

### Map Claim Codes to Categories

Translate internal codes to human-readable categories.

**Input Columns:**

| Column | Context Path |
| - | - |
| Loss Code | lossCode |

**Output Columns:**

| Column | Context Path |
| - | - |
| Category | lossCategory |
| Subcategory | lossSubcategory |
| Description | lossDescription |

**Rules:**

| Loss Code | Category | Subcategory | Description |
| - | - | - | - |
| WTR-001 | water | pipe\_burst | Pipe burst or leak |
| WTR-002 | water | flooding | External flooding |
| WTR-003 | water | appliance | Appliance malfunction |
| FIR-001 | fire | structural | Structural fire |
| FIR-002 | fire | electrical | Electrical fire |
| FIR-003 | fire | kitchen | Kitchen fire |
| THF-001 | theft | burglary | Burglary or break-in |
| THF-002 | theft | vehicle | Theft from vehicle |
| any | other | unknown | Uncategorized loss |

***

### Determine Payment Routing

Route payments based on amount and type.

**Input Columns:**

| Column | Context Path |
| - | - |
| Payment Amount | paymentAmount |
| Payment Type | paymentType |
| Customer Tenure | customerYears |

**Output Columns:**

| Column | Context Path |
| - | - |
| Approval Required | approvalRequired |
| Approver Level | approverLevel |
| Payment Method | paymentMethod |

**Rules:**

| Payment Amount | Payment Type | Customer Tenure | Approval Required | Approver Level | Payment Method |
| - | - | - | - | - | - |
| over 100000 | any | any | true | executive | wire |
| over 50000 | any | any | true | manager | wire |
| over 10000 | claim | any | true | supervisor | ach |
| over 10000 | refund | any | true | manager | ach |
| 10000 or less | any | 5 years or more | false | none | ach |
| 10000 or less | any | under 5 years | true | supervisor | check |
| any | any | any | true | supervisor | check |

***

### Route by Time of Day

Handle after-hours calls differently.

**Input Columns:**

| Column | Context Path |
| - | - |
| Hour | callHour |
| Is Weekend | isWeekend |
| Urgency | urgencyLevel |

**Output Columns:**

| Column | Context Path |
| - | - |
| Routing | routingDestination |
| Callback Required | callbackRequired |

**Rules:**

| Hour | Is Weekend | Urgency | Routing | Callback Required |
| - | - | - | - | - |
| any | any | emergency | on\_call\_team | false |
| 9 to 17 | false | any | live\_agents | false |
| any | true | high | on\_call\_team | false |
| any | true | any | voicemail | true |
| any | any | any | after\_hours\_queue | true |

***

## Multiple Matches and Hit Policies

By default, Decision Tables use **First Match** (first matching rule wins). Some implementations support other policies:

| Policy | Behavior |
| - | - |
| **First Match** | First matching rule wins (default) |
| **Unique** | Exactly one rule must match (error if multiple) |
| **Collect** | All matching rules outputs are collected |
| **Priority** | Rules have priority numbers and highest wins |

> [!NOTE]
>
> Liberate uses First Match policy. Structure your rules from most specific to most general.

***

## Best Practices

### Order Rules from Specific to General

Correct Order:

1. fire + injuries = critical (most specific)
2. fire = high
3. water + over 50000 = high
4. water = medium
5. any = standard (catch-all last)

Wrong Order:

1. any = standard (catches everything)
2. fire = high (never reached)

### Always Include a Catch-All Rule

Add a final rule with wildcards in all input columns to handle unexpected cases:

| claimType | amount | priority | action |
| - | - | - | - |
| ... | ... | ... | ... |
| any | any | standard | review |

### Keep Tables Focused

One Decision Table should handle one decision:

* Bad: One table for priority AND assignee AND SLA AND routing
* Good: Separate tables for each decision

### Use Descriptive Names

| Bad | Good |
| - | - |
| Decision Table | Route Claim by Type and Amount |
| DT1 | Determine State Requirements |

### Document Complex Rules

Add a Note Node before your Decision Table explaining the business logic:

```
Business Rule: Claims with injuries always get critical priority
regardless of type or amount. Fire claims are always high priority.
Water claims over 50k require senior adjusters.
```

***

## Testing Decision Tables

### Test Each Rule

Create test cases that exercise each row:

| Test Case | Input | Expected Output |
| - | - | - |
| Fire claim | claimType: fire, amount: 5000 | priority: high |
| Large water | claimType: water, amount: 75000 | priority: high |
| Small water | claimType: water, amount: 10000 | priority: medium |
| Unknown type | claimType: hail, amount: 5000 | priority: standard |

### Test Edge Cases

* Values at boundaries (over 50000 means test with 50000 and 50001)
* Null or missing values
* Unexpected input types
* Empty strings

### Test Rule Priority

Verify that more specific rules match before general rules when multiple could apply.

***

## Common Issues

### Wrong Rule Matches

**Symptom:** A general rule matches when a specific rule should.

**Fix:** Check rule order. Move specific rules above general rules.

### No Rule Matches

**Symptom:** Outputs are null or empty.

**Fix:** Add a catch-all rule at the bottom with wildcards in all inputs.

### Unexpected Null Handling

**Symptom:** Rules do not match when input is null.

**Fix:** Add explicit rules for null cases, or ensure inputs have default values before the Decision Table.

Before Decision Table, use Mapping Node:

```jsonata theme={null}
{
  "claimType": $.claimType ? $.claimType : "unknown"
}
```

### Numeric Comparisons Fail

**Symptom:** Over 50000 does not match when amount is 75000.

**Fix:** Verify the input is a number, not a string. Use a Mapping Node to convert if needed:

```jsonata theme={null}
{
  "amount": $number($.amount)
}
```

***

## Decision Table vs. Code Node

| Decision Table | Code Node |
| - | - |
| Visual, no code | Requires programming |
| Business users can update | Developer-maintained |
| Simple conditions | Complex logic |
| Fast to set up | More flexible |
| Easy to audit | Harder to review |
| Limited operators | Any logic possible |

**Use Decision Table when:**

* Rules are straightforward if/then logic
* Business users need to maintain rules
* Auditability is important
* You have many conditions but simple outcomes

**Use Code Node when:**

* Logic involves calculations
* You need loops or complex conditionals
* Rules cannot be expressed as simple conditions

***

## Next Steps

> [card] [Entity Table Node](https://docs.liberate.ai/workflows/nodes/entity-table-node.md)
>
> Look up static reference data from CSV

> [card] [Code Node](https://docs.liberate.ai/workflows/nodes/code-node.md)
>
> Use code for complex conditional logic

> [card] [Mapping Node](https://docs.liberate.ai/workflows/nodes/mapping-node.md)
>
> Simple conditionals with JSONata

> [card] [Workflow Examples](https://docs.liberate.ai/workflows/examples/fnol-workflow.md)
>
> See Decision Tables in action


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.