Argument format
Each action takes an array of argument objects:profile_id is almost always dynamic, reading the subject from context: { "var": "id" } on a profile context, or { "var": "profile_id" } on a transaction or transaction item context.
Every action validates its own arguments and rejects the whole reaction on a bad payload, so a 422 on save usually means a missing required argument or a handle that does not exist.
How the chain runs
Actions run insort_order order. An action that returns false stops the chain, and nothing after it runs. That is the mechanism behind every gate below, and it is why filter is conventionally sort_order 0 or 1.
Filtering
filter
Evaluates a condition and stops the chain when it is false. The most common action in any reaction.
Gates
These return a boolean rather than changing anything. They exist to stop a chain, so put them before the actions they protect.incentive.not-received
Passes only when the profile has not received the given incentives inside a window. Counts expired and redeemed ones, so it is a “not issued at all recently” check rather than “does not currently hold”.
transaction.count
Passes when the profile’s transaction count in a period equals count exactly.
Matching is an equality check, not a threshold, which makes it suited to “this is their Nth transaction” rules.
transaction.total
As transaction.count, but matches the profile’s spend total against total.
profile.done
Passes when every named context path holds a value. Used for profile-completion rules.
Rewards
reward.create
Issues a reward.
reward.expiry.extend
Extends the expiry of the reward in context by days.
reverse.reward.value
Reverses reward value for a profile, for example after a return.
invite.reward.create and join.from.invite.reward
The two halves of a referral: reward the inviter, and reward the joiner who used an invite. Both take the reward arguments above plus invite_handle (the custom attribute holding the invite code) and tier_reward_handles for tier-specific reward definitions.
Points
point.create
Issues a single point record.
points.create
Issues points for every qualifying item on a transaction, rather than one flat amount.
create.points.with.rate
Issues points through a Rate with spend and issue limits. Requires profile_id, definition, value, type, timezone, limit, and spend_limit. Optional transaction_item_id, date_range, is_return, linked_identity, location_type, name, code, expires_at, accrued_at.
redeem.point
Redeems points against an external endpoint.
finish.transaction.point
Finalises a pending point record, optionally limited to given SKUs. Requires point_id; optional sku array.
Tier points
tier-point.create
Issues tier points, which count toward tier progression rather than a spendable balance. Same shape as point.create: requires profile_id, amount, definition, with issued_at, accrued_at, transaction_id, check_rate, rate_priority, is_return, delay_return_points, and the location and context arguments optional.
tier-points.create
Per-item tier points for a transaction. Requires profile_id and definition; optional transaction_id, filter, issued_at, accrued_at, delay_return_points.
tier-point.create.with.region
Tier points with currency conversion across regions. Additionally requires currency, transaction_region, and profile_region, with optional convert_currency.
Benefits
benefit.create
Issues a benefit.
benefit.replace
Keeps a profile holding exactly one benefit from a mutually exclusive family, which is what tiered gifts need. Instead of a single definition it takes mappings, one entry per tier.
sort_order does two jobs. It picks the target, since the first matching mapping in sort_order sequence wins, and it establishes rank, which governs what happens on the way down:
- Moving up always issues the higher-tier benefit. An unredeemed lower-tier benefit is retired and the new one inherits its expiry rather than extending it. A redeemed one is left alone.
- Moving down does not hand back a lower-tier benefit the profile has already used at a higher tier, as long as that redemption still falls inside the benefit definition’s own period. Once that period has elapsed the entitlement reopens.
sort_order falls back to the order the mappings are declared in, so an existing configuration keeps working, but set it explicitly: it makes the tier order visible to whoever edits the reaction next.
update.benefit
Expires or extends a benefit the profile holds.
redeem.benefit
Records a redemption against a benefit the profile holds.
Credits
credit.create
Issues a credit. Requires profile_id and definition. Shares the reward issue-cap and expiry arguments (value, expires_at, delay_days, timezone, rounding, max_issue*), and adds gifting arguments: creator_profile_id, recipient_email, recipient_first_name, message, plus quantity, issue_per_item_quantity, external_id, external_namespace, and location_id.
Tiers
update.profile.tier
Assigns a tier or recalculates the profile’s tier.
tier.update
Sets the profile onto a specific tier definition. Requires profile_id and definition; optional trigger_event.
tier.calculate
Recalculates the profile’s tier from current data. Requires profile_id; optional disable_event to suppress the resulting event.
tier.maintain.instant
Applies instant tier maintenance. Takes count and unit together (days, weeks, months).
Achievements
achievement.increment
Increments an achievement.
achievement.increment.transaction
Increments based on the transaction in context, counting qualifying items. Requires profile_id and definition; optional item_filter and source_id.
achievement.increment.product-update
Increments from a product update. Requires id (the product) and definition.
achievement.progress.reset
Resets progress on an achievement. Requires profile_id and handle.
Profile updates
update.profile.status
Adds or removes profile statuses.
update.profile.status.with.expiry
As above, plus expires_at and timezone so the status lapses on its own.
update.profile.tags
Adds or removes tags. Requires profile_id; optional add and remove arrays, and trigger_event.
update.profile
Writes attributes onto the profile. Requires id and attributes; optional trigger_event.
update.profile.attributes.comms
Writes comms preferences. Requires id and attributes.
create.custom.attribute
Writes a custom attribute.
update.highest.status.attribute
Resolves the profile’s highest status in a group and writes that handle to a custom attribute. Only writes when the resolved status is higher than the stored one.
delete.profile
Deletes the profile. Requires id.
Outbound
target.send
Sends a Twig-templated payload to a configured Target.
See Targets.
webhook.send
Posts to a URL directly, without a Target.
Lists
lists.create
Creates one or more lists for a profile. Requires profile_id and lists, where each entry needs definition_handle and may carry tags and custom_fields (each field needing namespace, handle, and type).
update.list.item
Updates a list item’s status or position. Requires profile_id, definition_handle, sku, and attributes, where attributes may hold status and position.
delete.list.reservation
Deletes a reservation. Requires id.
Transactions and products
transaction.update
Writes attributes onto a transaction. Requires id and attributes; optional event to dispatch afterwards.
profile.transaction.event.dispatch
Re-dispatches an event for a profile’s transactions in a window. Requires profile_id and event; optional start_time, end_time, and filter.
update.variant.sellingfast
Flags a variant as selling fast. Requires selling_fast_threshold, transacted_at, and one of product_variant_id or sku; optional timezone.
Connections
connection.create
Connects two profiles. Requires connected_id, connector_id, and connection_definition. Optional status (draft, pending, accepted, rejected, hold, archived, break), external_id with external_id_type, name, meta, is_published, and organisation_id.
CX Manager may list an action that is not on this page. A few are deliberately left out: some exist to serve one instance’s specific arrangement and do not carry over to others, and some are registered but unused in practice. If you are considering one that is not documented here, ask before building on it.
Related
- Reactions for the concept and where actions sit
- Reactions Overview for building a reaction
- Reaction Filters and JSON Conditions
- Automation Queries for the query side
- Event Contexts for what
is_dynamiccan read