This reference covers all action types supported by the USSD DSL and the fields expected in inline action objects.
The flow validation API represents action-specific fields under a params object using camelCase (for example, responseMap and timeoutSeconds). The DSL format uses inline, snake_case fields (response_map, timeout).
Action Type Matrix
| Action Type | Aliases | Purpose |
| noop | - | Placeholder action with no side effects. |
| arithmetic | add, subtract, multiply, divide, modulo | Numeric calculations using operators. |
| env | environment | Read configuration or environment values. |
| set | - | Assign a literal or copied value to a variable. |
| inc | increment | Increment a numeric variable. |
| dec | decrement | Decrement a numeric variable. |
| delete | remove | Remove a variable from the session. |
| conditional | if | Route based on comparisons and logical operators. |
| switch | - | Route based on exact, range, or regex multi-case matching. |
| http | http_call, api_call | Make an HTTP request with optional response mapping. |
| grpc | - | Invoke a gRPC method with request/response mapping. |
| string | concat, substring, upper, lower, trim, split, format | Transform string values. |
| validate | - | Validate input with patterns, ranges, or type coercion. |
| crypto | hash, encrypt, decrypt | Hash, encrypt, or decrypt sensitive values. |
| send_sms | - | Send an SMS message through the Tech231 SMS API. |
| send_otp | - | Send a one-time password through the Tech231 OTP API. |
Arithmetic (arithmetic)
Code
{ name = "apply-fee" type = "arithmetic" op = "subtract" left = "{{balance}}" right = 50 target = "net_balance" precision = 2}
Field
Required
Description
op
Yes
add, subtract, multiply, divide, modulo.
left
Yes
Left operand (literal or variable reference).
right
Yes
Right operand (literal or variable reference).
target
Yes
Variable to store the result.
precision
No
Decimal precision for division (default: 2).
rounding_mode
No
Rounding mode for division (to_even (Bankers), away_from_zero). Default: to_even.
Environment (env)
Code
{ name = "currency-config" type = "env" key = "CURRENCY" fallback = "USD" target = "currency"}
Field
Required
Description
key
Yes
Configuration key or environment variable.
fallback
No
Fallback value if key is missing.
target
Yes
Variable to store the value.
Set (set)
Code
{ name = "store-selection" type = "set" target = "selected_plan" value = "{{session.input}}"}
Field
Required
Description
target
Yes
Variable to store the value.
value
No
Literal value to store.
source
No
Source variable to copy (mutually exclusive with value, from alias supported).
Increment/Decrement (inc, dec)
Code
{ type = "inc", target = "retry_count", by = 1 }
Field
Required
Description
target
Yes
Variable to increment/decrement.
by
No
Amount to change by (default: 1).
Delete (delete)
Code
{ type = "delete", target = "pin" }
Field
Required
Description
target
Yes
Variable to remove.
Conditional (conditional)
Code
{ name = "balance-check" type = "conditional" lhs = "{{balance}}" op = ">=" rhs = 100 true_target = "EligibleMenu" false_target = "IneligibleMenu" null_behavior = "false"}
Field
Required
Description
lhs
Yes
Left operand for comparison.
op
Yes
==, !=, <, >, <=, >=, or aliases (eq, ne, lt, gt, le, ge).
Multi-case branching that matches a source value against ordered cases. Each case can use exact string matching, numeric range matching, or regex pattern matching. First matching case wins; falls back to the default target when no case matches.
Code
{ name = "route-by-choice" type = "switch" source = "{{session.input}}" cases = [ { value = "1", target = "BalanceMenu" }, { value = "2", target = "TransferMenu" }, { op = "range", min = "10", max = "50", inclusive_max = false, target = "MidRangeMenu" }, { op = "regex", pattern = "^[A-Z]+$", target = "LetterMenu" } ] default_target = "InvalidChoiceMenu" target = "selected_route"}
Field
Required
Description
source
Yes
Operand or variable reference to match against.
cases
Yes (non-empty array)
Ordered list of case objects (see below).
default_target
Yes
Block name to route to when no case matches.
target
No
Variable to store the matched target name (for diagnostic/chain use).
Case Object Fields
Each entry in the cases array is an object. The op field selects the matching strategy.
Field
Required
Description
op
No (default "exact")
Matching operator: "exact", "range", or "regex".
target
Yes
Block name to route to when this case matches.
When op = "exact" (default)
Field
Required
Description
value
Yes
Literal string to match with ordinal equality.
When op = "range"
Field
Required
Description
min
Yes
Lower bound of the numeric range.
max
Yes
Upper bound of the numeric range.
inclusive_min
No (default true)
When true, the lower bound is inclusive (.ge. min). Set false for .gt. min.
inclusive_max
No (default true)
When true, the upper bound is inclusive (.le. max). Set false for .lt. max.
Cases are evaluated in the order they appear in the array. Matching stops at the first case whose operator succeeds. Always include a default_target for the fallback path.
Send SMS (send_sms)
Send a raw SMS message through the Tech231 SMS API. Requires per-tenant Zitadel service-account credentials configured in the secrets engine.
Code
{ name = "send-confirmation" type = "send_sms" recipient = "{{phone}}" message = "Your order #{{order_id}} has been confirmed." sender_id = "TECH231" target = "sms_result"}
Field
Required
Description
recipient
Yes
Phone number in E.164 format. Supports variable references.
message
Yes
SMS content. Supports variable references and templates.
sender_id
No
Alphanumeric sender ID. If omitted, uses the tenant default.
target
Yes
Variable to store the API response.
Send OTP (send_otp)
Send a one-time password (OTP) through the Tech231 OTP API. Requires per-tenant Zitadel service-account credentials configured in the secrets engine.