Automations
Automations (formerly "earning rules") are workspace-scoped rules that react to events — transactions, custom events, loyalty events, field changes, pass lifecycle events, schedules and referrals — and apply effects such as awarding points, granting rewards, assigning tiers or calling webhooks. The live execution engine runs inside the wallethero-hooks extension; the endpoints below cover CRUD, editor metadata, formula validation, dry-run simulation, and execution history/stats.
Auth: every endpoint is workspace-scoped and requires a Bearer token belonging to a member of the target workspace (enforced by createWorkspaceGuard).
A few shared concepts referenced throughout:
trigger_type— one oftransaction,custom_event,field_change,pass_lifecycle,time_based,loyalty,referral.trigger_config— a free-form object whose recognised keys depend ontrigger_type(e.g.event_types,min_amount/max_amount,field_names,change_direction,schedule,role).conditions— an array of typed conditions (expression,segment,tier,wallet_balance,client_metric), AND-combined.effects— an array of typed effects (earn_points,deduct_points,give_reward,update_client_field,send_push,call_webhook,assign_tier,remove_tier,switch_template); at least one is required.limits— optional caps:total_budget,per_client_budget,executions_per_client({ interval, value }),total_executions.activity_window— optional{ start_date, end_date }ISO timestamps.expiry_override— optional{ expiry_days, pending_days }for points awarded by the rule.
List automations
GET /wallethero-api/workspace/:workspaceId/automations
Returns all automation rules for the workspace, ordered by priority ascending then id.
Auth: Bearer token — workspace member.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
workspaceId | string (UUID) | Workspace identifier |
Query Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
active | boolean ("true"/"false") | No | — | When provided, returns only rules with the matching active value |
Example Request
curl "https://api.wallethero.app/wallethero-api/workspace/WORKSPACE_ID/automations?active=true" \
-H "Authorization: Bearer YOUR_TOKEN"Response (200)
{
"data": [
{
"id": "8f3b...",
"workspace_id": "WORKSPACE_ID",
"name": "Double points on big spend",
"description": "Award 2x on purchases over 100",
"active": true,
"priority": 0,
"trigger_type": "transaction",
"trigger_config": { "event_types": ["purchase"], "min_amount": 100 },
"conditions": [],
"effects": [
{ "type": "earn_points", "wallet_type_code": "points", "amount_type": "expression", "amount_expression": "event.amount * 2" }
],
"limits": {},
"activity_window": {},
"expiry_override": null
}
]
}SDK
const { data } = await wh.automations.list(workspaceId, { active: true });Create automation
POST /wallethero-api/workspace/:workspaceId/automations
Creates a new automation rule. The workspace_id is taken from the path. Effects and conditions are validated to ensure referenced rewards, wallet types, webhooks, tiers, templates and segments belong to the workspace.
Auth: Bearer token — workspace member.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
workspaceId | string (UUID) | Workspace identifier |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string (1–255) | Yes | Display name |
description | string (≤2000) | No | Optional description |
active | boolean | No | Defaults to true |
priority | integer (≥0) | No | Evaluation order, lower runs first. Defaults to 0 |
trigger_type | enum | Yes | One of transaction, custom_event, field_change, pass_lifecycle, time_based, loyalty, referral |
trigger_config | object | No | Trigger-specific config. Defaults to {} |
conditions | condition[] | No | AND-combined conditions. Defaults to [] |
effects | effect[] | Yes | At least one effect |
limits | object | No | Execution/budget caps. Defaults to {} |
activity_window | object | No | { start_date, end_date }. Defaults to {} |
expiry_override | object | null | No | { expiry_days, pending_days } |
Condition shapes (discriminated on type):
type | Fields |
|---|---|
expression | expression: string |
segment | segment_id: UUID |
tier | tier_id: UUID |
wallet_balance | wallet_type_code: string, operator: eq|neq|gt|gte|lt|lte, value: number |
client_metric | metric: transaction_count|total_spending|points_earned|referrals_completed|days_since_last_transaction, period_days?: int, wallet_type_code?: string, operator: eq|neq|gt|gte|lt|lte, value: number |
Effect shapes (discriminated on type):
type | Fields |
|---|---|
earn_points | wallet_type_code: string, amount_type: fixed|expression, amount?: number, amount_expression?: string |
deduct_points | wallet_type_code: string, amount: number |
give_reward | reward_id: UUID |
update_client_field | field_name: string, value_expression: string |
send_push | title?: string, body: string. On time_based rules (scheduled/date broadcasts) this effect honors GDPR marketing consent: clients with marketing_consent !== true are skipped (skipped: "no_marketing_consent"). Event-triggered pushes (points earned, tier changed) are operational and not filtered |
call_webhook | webhook_id: UUID |
assign_tier | tier_id: UUID (must be an exclusive tier), duration_days?: int | null |
remove_tier | tier_id?: UUID |
switch_template | template_id: UUID, duration_days?: int | null |
Example Request
curl -X POST "https://api.wallethero.app/wallethero-api/workspace/WORKSPACE_ID/automations" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Welcome bonus",
"trigger_type": "pass_lifecycle",
"trigger_config": { "event_types": ["pass_installed"] },
"effects": [
{ "type": "earn_points", "wallet_type_code": "points", "amount_type": "fixed", "amount": 50 }
]
}'Response (201)
{
"data": {
"id": "8f3b...",
"workspace_id": "WORKSPACE_ID",
"name": "Welcome bonus",
"active": true,
"priority": 0,
"trigger_type": "pass_lifecycle",
"trigger_config": { "event_types": ["pass_installed"] },
"conditions": [],
"effects": [
{ "type": "earn_points", "wallet_type_code": "points", "amount_type": "fixed", "amount": 50 }
],
"limits": {},
"activity_window": {},
"expiry_override": null
}
}SDK
const { data } = await wh.automations.create(workspaceId, {
name: "Welcome bonus",
trigger_type: "pass_lifecycle",
trigger_config: { event_types: ["pass_installed"] },
effects: [{ type: "earn_points", wallet_type_code: "points", amount_type: "fixed", amount: 50 }],
});Get editor metadata
GET /wallethero-api/workspace/:workspaceId/automations/metadata
Returns static metadata for building the automation editor UI: available trigger types, event categories, event types grouped by category, and the expression variables/functions available in formulas.
Auth: Bearer token — workspace member.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
workspaceId | string (UUID) | Workspace identifier |
Example Request
curl "https://api.wallethero.app/wallethero-api/workspace/WORKSPACE_ID/automations/metadata" \
-H "Authorization: Bearer YOUR_TOKEN"Response (200)
{
"data": {
"trigger_types": [
{ "value": "transaction", "label": "Transaction", "description": "When a purchase or refund happens.", "event_category": "transaction" }
],
"event_categories": [
{ "value": "transaction", "label": "Transaction" }
],
"event_types_by_category": {
"transaction": ["purchase", "refund"],
"loyalty": ["tier_promoted", "tier_demoted", "reward_redeemed", "points_earned", "points_spent"],
"field_change": ["field_updated", "field_increment", "field_decrement"],
"pass_lifecycle": ["pass_installed", "pass_uninstalled", "pass_registered", "template_changed"],
"referral": ["referral_completed"]
},
"expression_variables": [],
"expression_functions": []
}
}SDK
const { data } = await wh.automations.getMetadata(workspaceId);Validate a formula
POST /wallethero-api/workspace/:workspaceId/automations/validate-formula
Parses and dry-evaluates an expression against dummy variables to surface syntax errors, unknown identifiers and (optionally) return-type mismatches — without touching real data.
Auth: Bearer token — workspace member.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
workspaceId | string (UUID) | Workspace identifier |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
expression | string (≤2000) | Yes | The formula to validate |
expected_type | enum (number, boolean, string) | No | If set, the result type must match or validation fails |
Example Request
curl -X POST "https://api.wallethero.app/wallethero-api/workspace/WORKSPACE_ID/automations/validate-formula" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "expression": "event.amount * 2", "expected_type": "number" }'Response (200)
Valid:
{ "data": { "valid": true, "returnType": "number" } }Invalid:
{ "data": { "valid": false, "error": { "message": "Unexpected token", "position": 9 } } }SDK
const { data } = await wh.automations.validateFormula(workspaceId, {
expression: "event.amount * 2",
expected_type: "number",
});List executions (workspace-wide)
GET /wallethero-api/workspace/:workspaceId/automations/executions
Returns automation rule executions across the whole workspace, newest first, with optional filtering and pagination.
Auth: Bearer token — workspace member.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
workspaceId | string (UUID) | Workspace identifier |
Query Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
automation_rule_id | string (UUID) | No | — | Filter to one rule |
client_id | string (UUID) | No | — | Filter to one client |
status | enum (success, failed, skipped) | No | — | Filter by execution status |
from_date | string | No | — | Only executions on/after this timestamp |
to_date | string | No | — | Only executions on/before this timestamp |
limit | integer (1–1000) | No | 50 | Page size |
offset | integer (≥0) | No | 0 | Page offset |
Example Request
curl "https://api.wallethero.app/wallethero-api/workspace/WORKSPACE_ID/automations/executions?status=success&limit=20" \
-H "Authorization: Bearer YOUR_TOKEN"Response (200)
{
"data": [
{
"id": "exec-1",
"automation_rule_id": "8f3b...",
"client_id": "client-1",
"workspace_id": "WORKSPACE_ID",
"trigger_event_id": "evt-1",
"effects_applied": [{ "type": "earn_points", "amount": 50 }],
"points_awarded": 50,
"status": "success",
"error_message": null,
"executed_at": "2026-06-01T12:00:00.000Z"
}
],
"meta": { "total_count": 1, "returned_count": 1, "offset": 0 }
}SDK
const result = await wh.automations.listExecutions(workspaceId, { status: "success", limit: 20 });Get an automation
GET /wallethero-api/workspace/:workspaceId/automations/:id
Returns a single automation rule by id. Fails with a not-found error if the rule does not belong to the workspace.
Auth: Bearer token — workspace member.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
workspaceId | string (UUID) | Workspace identifier |
id | string (UUID) | Automation rule identifier |
Example Request
curl "https://api.wallethero.app/wallethero-api/workspace/WORKSPACE_ID/automations/RULE_ID" \
-H "Authorization: Bearer YOUR_TOKEN"Response (200)
{
"data": {
"id": "RULE_ID",
"workspace_id": "WORKSPACE_ID",
"name": "Welcome bonus",
"active": true,
"priority": 0,
"trigger_type": "pass_lifecycle",
"trigger_config": { "event_types": ["pass_installed"] },
"conditions": [],
"effects": [{ "type": "earn_points", "wallet_type_code": "points", "amount_type": "fixed", "amount": 50 }],
"limits": {},
"activity_window": {},
"expiry_override": null
}
}SDK
const { data } = await wh.automations.get(workspaceId, ruleId);Update an automation
PUT /wallethero-api/workspace/:workspaceId/automations/:idPATCH /wallethero-api/workspace/:workspaceId/automations/:id
Updates an existing automation rule. Both PUT and PATCH are accepted and behave identically (the published SDK uses PATCH). All fields are optional; only the fields provided are changed. If effects is supplied it must contain at least one effect.
Auth: Bearer token — workspace member.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
workspaceId | string (UUID) | Workspace identifier |
id | string (UUID) | Automation rule identifier |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string (1–255) | No | Display name |
description | string | null (≤2000) | No | Description |
active | boolean | No | Enable/disable |
priority | integer (≥0) | No | Evaluation order |
trigger_type | enum | No | See create |
trigger_config | object | No | Trigger-specific config |
conditions | condition[] | No | See create |
effects | effect[] | No | If present, must be non-empty |
limits | object | No | See create |
activity_window | object | No | { start_date, end_date } |
expiry_override | object | null | No | { expiry_days, pending_days } |
Example Request
curl -X PATCH "https://api.wallethero.app/wallethero-api/workspace/WORKSPACE_ID/automations/RULE_ID" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "active": false, "priority": 5 }'Response (200)
{ "data": { "id": "RULE_ID", "active": false, "priority": 5, "...": "..." } }SDK
const { data } = await wh.automations.update(workspaceId, ruleId, { active: false, priority: 5 });
// convenience helpers:
await wh.automations.activate(workspaceId, ruleId);
await wh.automations.deactivate(workspaceId, ruleId);Delete an automation
DELETE /wallethero-api/workspace/:workspaceId/automations/:id
Permanently deletes an automation rule. Fails if the rule does not belong to the workspace.
Auth: Bearer token — workspace member.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
workspaceId | string (UUID) | Workspace identifier |
id | string (UUID) | Automation rule identifier |
Example Request
curl -X DELETE "https://api.wallethero.app/wallethero-api/workspace/WORKSPACE_ID/automations/RULE_ID" \
-H "Authorization: Bearer YOUR_TOKEN"Response (200)
{ "message": "Automation rule deleted successfully" }SDK
await wh.automations.delete(workspaceId, ruleId);Simulate automations
POST /wallethero-api/workspace/:workspaceId/automations/simulate
Performs a dry run for a single client and synthetic event: evaluates which active rules would match, why non-matching rules are skipped, and estimates the effects each matching rule would apply — without executing anything.
Auth: Bearer token — workspace member.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
workspaceId | string (UUID) | Workspace identifier |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
client_id | string (UUID) | Yes | Client to simulate against |
event | object | Yes | The synthetic event (see below) |
event.event_category | string | Yes | e.g. transaction, loyalty, field_change, pass_lifecycle, engagement |
event.event_type | string | Yes | e.g. purchase, points_earned, pass_installed |
event.amount | number | No | Transaction amount |
event.field_name | string (≤100) | No | For field-change events |
event.old_value | string | null | No | Previous field value |
event.new_value | string | null | No | New field value |
event.metadata | object | No | Arbitrary event metadata |
Example Request
curl -X POST "https://api.wallethero.app/wallethero-api/workspace/WORKSPACE_ID/automations/simulate" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"client_id": "CLIENT_ID",
"event": { "event_category": "transaction", "event_type": "purchase", "amount": 120 }
}'Response (200)
{
"data": {
"matching_rules": [
{
"rule_id": "8f3b...",
"rule_name": "Double points on big spend",
"would_execute": true,
"estimated_effects": [
{ "type": "earn_points", "wallet_type_code": "points", "estimated_amount": 240 }
]
},
{
"rule_id": "a1c2...",
"rule_name": "Members only bonus",
"would_execute": false,
"skip_reason": "Conditions not met",
"estimated_effects": []
}
]
}
}skip_reason may be one of: Outside activity window, Trigger config mismatch, Conditions not met, Limits exceeded.
SDK
No SDK method — call the REST endpoint directly.
List executions for a rule
GET /wallethero-api/workspace/:workspaceId/automations/:id/executions
Returns the execution history for a single automation rule, newest first, with optional filtering and pagination.
Auth: Bearer token — workspace member.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
workspaceId | string (UUID) | Workspace identifier |
id | string (UUID) | Automation rule identifier |
Query Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
client_id | string (UUID) | No | — | Filter to one client |
status | enum (success, failed, skipped) | No | — | Filter by status |
from_date | string | No | — | On/after this timestamp |
to_date | string | No | — | On/before this timestamp |
limit | integer (1–1000) | No | 50 | Page size |
offset | integer (≥0) | No | 0 | Page offset |
Note: the
automation_rule_idquery param is ignored here — the rule is taken from the path:id.
Example Request
curl "https://api.wallethero.app/wallethero-api/workspace/WORKSPACE_ID/automations/RULE_ID/executions?status=success&limit=50" \
-H "Authorization: Bearer YOUR_TOKEN"Response (200)
{
"data": [
{
"id": "exec-1",
"automation_rule_id": "RULE_ID",
"client_id": "client-1",
"workspace_id": "WORKSPACE_ID",
"effects_applied": [{ "type": "earn_points", "amount": 50 }],
"points_awarded": 50,
"status": "success",
"error_message": null,
"executed_at": "2026-06-01T12:00:00.000Z"
}
],
"meta": { "total_count": 1, "returned_count": 1, "offset": 0 }
}SDK
const result = await wh.automations.getRuleExecutions(workspaceId, ruleId, { limit: 50 });Get rule stats
GET /wallethero-api/workspace/:workspaceId/automations/:id/stats
Returns aggregate execution statistics for a single automation rule.
Auth: Bearer token — workspace member.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
workspaceId | string (UUID) | Workspace identifier |
id | string (UUID) | Automation rule identifier |
Example Request
curl "https://api.wallethero.app/wallethero-api/workspace/WORKSPACE_ID/automations/RULE_ID/stats" \
-H "Authorization: Bearer YOUR_TOKEN"Response (200)
{
"data": {
"total_executions": 1240,
"successful_executions": 1180,
"failed_executions": 12,
"skipped_executions": 48,
"total_points_awarded": 59000,
"unique_clients": 870,
"last_executed_at": "2026-06-15T09:30:00.000Z"
}
}total_points_awarded and unique_clients are counted over successful executions only.
SDK
No SDK method — call the REST endpoint directly.
Duplicate an automation
POST /wallethero-api/workspace/:workspaceId/automations/:id/duplicate
Creates a copy of an existing automation rule within the same workspace. The copy is created inactive (active: false) and carries over the trigger, conditions, effects, limits, activity window and expiry override of the original.
Auth: Bearer token — workspace member.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
workspaceId | string (UUID) | Workspace identifier |
id | string (UUID) | Automation rule to copy |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | No | Name for the copy. Defaults to Copy of <original name> |
Example Request
curl -X POST "https://api.wallethero.app/wallethero-api/workspace/WORKSPACE_ID/automations/RULE_ID/duplicate" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "name": "Welcome bonus (draft)" }'Response (201)
{
"data": {
"id": "new-rule-id",
"workspace_id": "WORKSPACE_ID",
"name": "Welcome bonus (draft)",
"active": false,
"trigger_type": "pass_lifecycle",
"effects": [{ "type": "earn_points", "wallet_type_code": "points", "amount_type": "fixed", "amount": 50 }],
"...": "..."
}
}SDK
const { data } = await wh.automations.duplicate(workspaceId, ruleId, "Welcome bonus (draft)");