Decision Tables
A Decision Table represents business rules as rows. Condition columns describe when a row applies; result columns describe what that row writes. Tables are particularly useful when policy owners need to review logic without reading code.
Typical uses include eligibility, pricing bands, referral reasons, product selection, routing, and regulatory classification.
When a Decision Table is the right choice
Choose a table when the logic can be expressed as combinations of typed conditions and results. Choose a Ruleset when actions must increment, append, remove, or clear data; a Scorecard when independent factors contribute points; Coding when the algorithm is more naturally procedural; or a Workflow when several decisions and integrations must be coordinated.
Configure the contract
In Settings:
- Select an input Data Model. Its fields become available as condition columns.
- Select an output Data Model. Its fields become available as result columns.
- Enable Auto-map Input to Output only when compatible request fields should be copied into the response.
- Add a description that explains the table's business purpose and ownership.
The public input/output shape comes from these models, not from the visual width or order of table columns.
Build the table
In Designer, add condition and result columns, then add rules as rows.
For every condition cell:
- choose an operation appropriate to the field type;
- enter the comparison value or range;
- use Anything only when the condition is intentionally unrestricted.
For every result cell, enter a typed literal or select a supported function. Empty results do not automatically mean “preserve the previous value”; verify the behavior you expect with an overlapping-row test.
Worked example: loan eligibility
Assume the input contains applicant.age, applicant.annualIncome, applicant.existingDebt, and requestedAmount. The output contains decision, riskBand, and reason.
| Age | Income | Existing debt | Requested amount | Decision | Risk band | Reason |
|---|---|---|---|---|---|---|
| Less than 18 | Anything | Anything | Anything | Declined | High | Applicant is under 18 |
| 18 or greater | 60,000 or greater | Less than 15,000 | 30,000 or less | Approved | Low | Meets standard policy |
| 18 or greater | 40,000–59,999 | Less than 20,000 | 20,000 or less | Review | Medium | Manual affordability review |
| Anything | Anything | Anything | Anything | Declined | High | Outside lending policy |
Example request:
{
"applicant": {
"age": 34,
"annualIncome": 78000,
"existingDebt": 8500
},
"requestedAmount": 25000
}
Example response:
{
"decision": "Approved",
"riskBand": "Low",
"reason": "Meets standard policy"
}
This table has an intentional fallback row. Without it, an unmatched input may produce an incomplete response.
Understand matching rows
More than one row can match an input. This is useful when separate rows write different results, but dangerous when they write the same output path. Later matching writes can replace an earlier value.
Consider these rows:
| Customer tier | Requested amount | Result field | Value |
|---|---|---|---|
| Gold | Anything | discount | 0.05 |
| Anything | More than 10,000 | discount | 0.02 |
A Gold customer requesting 20,000 matches both. If both write discount, the result depends on their application order. Resolve this by making conditions mutually exclusive or by deliberately ordering and testing the override.
Values, ranges, lists, and nulls
Operations are type-aware. Use numeric fields for numeric comparisons rather than text representations such as "25000". Date comparisons should receive date values in the expected contract format. Membership operations accept a set of possible values; null operations distinguish a missing/empty business value from ordinary text.
Always test:
- values immediately below, exactly on, and immediately above a range boundary;
nulland omitted optional fields;- empty and populated collections;
- unknown category values;
- an input that matches the fallback only;
- an input that intentionally matches multiple rows.
See the operations reference for the available families.
Functions in conditions and results
Where the cell offers a function, use the Rich Editor to build a dynamic comparison or result from available fields. Prefer a literal when the value is fixed; it is easier for reviewers to understand. Use Coding for longer algorithms rather than hiding substantial procedural logic inside many table cells.
Test and debug
Open Testing Zone, select an environment with the table deployed, and enter a model-valid payload. Debug mode explains the evaluated conditions and applied results. Save each important scenario as a named test, for example:
Decline applicant under minimum ageApprove standard low-risk applicationRefer medium income at exact limitFallback when country is unsupported
Expected-result assertions should target the business outcome fields, not incidental formatting.
Use a table in a workflow
Add a Rule node, select the Decision Table and version, then map upstream fields to its input and its output to the next node. The workflow deployment includes the referenced table and Data Model dependencies. Debug the mapping first when a correct table behaves differently inside a workflow.
Release checklist
- Input and output models describe the intended public contract.
- Every row has a clear business meaning.
- Wildcards and overlaps are intentional.
- Boundary, null, fallback, and overlap tests pass.
- The version to deploy is the version reviewed.
- Dependencies appear in the deployment preview.
- Analytics is enabled only if storing execution payloads is appropriate.
Common problems
| Symptom | Check |
|---|---|
| No rule appears to apply | Missing fallback, wrong field mapping, or value has a different type |
| Unexpected rule also applies | An Anything, range, or broad membership condition overlaps another row |
| Correct result is overwritten | Multiple matching rows write the same output field |
| Designer test differs from API | API key points to an environment with another deployed version |
| A column is unavailable | The wrong Data Model is selected or its new version is not saved |