Appearance
Workflow Actions
An action is a side-effect that fires when a transition runs. Each transition can have multiple actions in order. Actions are fire-and-forget - errors are logged, never block the transition.
Adding an action to a transition
- Go to Settings -> Workflows & Statuses.
- Click a transition on the flowchart.
- Click + Add Action in the inspector panel.
- Pick an action type from the dropdown.
- Fill in any config fields.
- Save.
Actions run in sort_order when the transition fires.
Action types
Invoice actions
| Action | Config | What it does |
|---|---|---|
send_invoice_email | - | Emails the invoice to all linked client emails |
send_overdue_notice | - | Overdue reminder email |
send_paid_confirmation | - | Payment receipt |
share_invoice | - | Creates a public share token for the invoice |
unshare_invoice | - | Invalidates the invoice's share token |
lock_invoice_editing | - | Prevents editing while the invoice is in this status |
unlock_invoice_editing | - | Re-enables editing |
Session / event actions
| Action | Config | What it does |
|---|---|---|
send_event_day_page | - | Emails the event day page link to clients |
send_reminder_email | hours_before (default 24) | Sends a reminder before session start |
send_booking_confirmation | - | Confirms a booking to the client |
send_booking_rejection | - | Notifies a rejected booking |
send_cancellation_notice | - | Notifies a cancelled session |
send_reschedule_notification | - | Notifies a rescheduled session |
send_booking_cancellation | - | Cancels a booking via email |
send_new_request_alert | - | Alerts the owner of a new booking request |
Client actions
| Action | Config | What it does |
|---|---|---|
send_welcome_email | - | Welcome email for new clients |
send_reengagement_email | - | Re-engagement email for dormant clients |
send_feedback_form | form_id | Emails a feedback form link with a submission token |
Staff actions
| Action | Config | What it does |
|---|---|---|
send_schedule_update | - | Emails assigned staff about a schedule change |
send_payroll_notification | - | Emails a payroll breakdown to staff |
send_announcement | announcement_id (optional) | Emails all staff |
General actions
| Action | Config | What it does |
|---|---|---|
send_custom_email | subject, body_html | Any custom email to entity contacts |
create_notification | title, message, link | In-app notification |
share_link | share_type (schedule / invoice / booking) | Creates a share token |
unshare_link | share_type | Invalidates a share token |
Integration actions
| Action | Config | What it does |
|---|---|---|
call_webhook | webhook_config_id | Fires a saved webhook config |
call_api | url, method, headers, body_template | Raw HTTP call with templated body |
Recipient resolution
For email actions, FoxCLM resolves recipients based on the entity type:
- Invoice actions:
invoice_clients -> clients -> client_info.email - Session actions:
event_clients -> clients -> client_info.email - Client actions: the client's email
- Staff actions:
staff.emailorstaff_eventsassignments - Owner notifications:
users.email
If no email is found, the action silently skips. You'll see the result in the workflow log.
Template placeholders
Email bodies and webhook payloads support placeholder interpolation:
{{field}} // entity field: {{invoice_number}}, {{start_date}}
{{custom.field_name}} // custom field by name
{{client.name}} // linked client data
{{staff.name}} // linked staff dataThe call_api action supports dotted path syntax (e.g. client.address.city) for nested access.
Webhook context injection
When call_webhook fires, the payload includes a metadata block automatically:
json
{
"_workflow": {
"from_status": "Sent",
"to_status": "Paid",
"entity_type": "invoice"
},
...your entity payload...
}Raw API calls
call_api is the escape hatch for any HTTP integration:
- URL: full URL (supports placeholders)
- Method: GET / POST / PUT / PATCH / DELETE
- Headers: JSON object with auth and content type
- Body template: templated body string
Use this for Slack webhooks, Zapier triggers, internal APIs, or any service that doesn't have a dedicated integration.
Action queue and retry
Actions insert into a workflow_action_queue table. A worker processes the queue every 10 seconds. Failed actions retry up to 3 times with exponential backoff before being marked dead.
Check the workflow log for dead actions - these usually indicate a misconfigured webhook URL or auth failure.
Depth limit
A workflow action cannot trigger another workflow. Specifically, if an action moves an entity to a new status, that new status transition's actions do not fire. This prevents infinite loops.
If you need chained automation, fire an action that directly does the work rather than triggering another status transition.
Next steps
- Workflows & Statuses - build the transitions that actions attach to
- Webhooks & API - configure webhook targets for
call_webhook
